fix: panic on resume and pause download before starting to allow file priority selection
This commit is contained in:
parent
368bc27eaa
commit
264d73cdc5
5 changed files with 55 additions and 7 deletions
1
dummy.torrent
Normal file
1
dummy.torrent
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
d8:announce15:http://a.b.c/tr13:creation datei1e4:infod6:lengthi100e4:name9:dummy.txt12:piece lengthi16384e6:pieces20:12345678901234567890ee
|
||||||
|
|
@ -65,6 +65,10 @@ func (c *Controller) StartTorrent(path, outputRoot string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Controller) StartTorrentDownload() {
|
||||||
|
c.engine.StartDownload()
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Controller) DownloadMagnet(magnetURI string) error {
|
func (c *Controller) DownloadMagnet(magnetURI string) error {
|
||||||
cfg, _ := config.Load()
|
cfg, _ := config.Load()
|
||||||
outDir := "."
|
outDir := "."
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ type Engine struct {
|
||||||
portManager *portforward.PortManager
|
portManager *portforward.PortManager
|
||||||
|
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
|
downloadCtx context.Context
|
||||||
|
|
||||||
incomingConns chan net.Conn
|
incomingConns chan net.Conn
|
||||||
|
|
||||||
|
|
@ -345,6 +346,9 @@ func (e *Engine) LoadTorrent(path, outputRoot string) error {
|
||||||
|
|
||||||
downloadCtx, cancel := context.WithCancel(context.Background())
|
downloadCtx, cancel := context.WithCancel(context.Background())
|
||||||
e.swapCancel(cancel)
|
e.swapCancel(cancel)
|
||||||
|
e.mu.Lock()
|
||||||
|
e.downloadCtx = downloadCtx
|
||||||
|
e.mu.Unlock()
|
||||||
|
|
||||||
if strings.HasPrefix(path, "magnet:") {
|
if strings.HasPrefix(path, "magnet:") {
|
||||||
go e.loadMagnet(downloadCtx, path, outputRoot)
|
go e.loadMagnet(downloadCtx, path, outputRoot)
|
||||||
|
|
@ -360,10 +364,38 @@ func (e *Engine) LoadTorrent(path, outputRoot string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
e.startTorrent(downloadCtx, tf, outputRoot)
|
e.mu.Lock()
|
||||||
|
e.torrent = tf
|
||||||
|
if tf.InfoHash != [20]byte{} && len(tf.PieceHashes) > 0 {
|
||||||
|
e.totalPieces = len(tf.PieceHashes)
|
||||||
|
e.pieceStates = make([]PieceState, len(tf.PieceHashes))
|
||||||
|
e.outputPath = buildOutputPath(tf, outputRoot)
|
||||||
|
}
|
||||||
|
e.phase = "stopped"
|
||||||
|
e.mu.Unlock()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Engine) StartDownload() {
|
||||||
|
e.mu.Lock()
|
||||||
|
tf := e.torrent
|
||||||
|
out := e.outputRoot
|
||||||
|
phase := e.phase
|
||||||
|
|
||||||
|
if tf == nil || phase != "stopped" && phase != "failed" {
|
||||||
|
e.mu.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadCtx, cancel := context.WithCancel(context.Background())
|
||||||
|
e.downloadCtx = downloadCtx
|
||||||
|
e.cancel = cancel
|
||||||
|
e.mu.Unlock()
|
||||||
|
|
||||||
|
go e.startTorrent(downloadCtx, tf, out)
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Engine) loadMagnet(ctx context.Context, uri, outputRoot string) {
|
func (e *Engine) loadMagnet(ctx context.Context, uri, outputRoot string) {
|
||||||
ml, err := magnet.Parse(uri)
|
ml, err := magnet.Parse(uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -423,7 +455,13 @@ func (e *Engine) loadMagnet(ctx context.Context, uri, outputRoot string) {
|
||||||
tf.Name = hex.EncodeToString(ml.InfoHash[:])
|
tf.Name = hex.EncodeToString(ml.InfoHash[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
e.startTorrent(ctx, tf, outputRoot)
|
e.mu.Lock()
|
||||||
|
e.torrent = tf
|
||||||
|
e.totalPieces = len(tf.PieceHashes)
|
||||||
|
e.pieceStates = make([]PieceState, len(tf.PieceHashes))
|
||||||
|
e.outputPath = buildOutputPath(tf, outputRoot)
|
||||||
|
e.phase = "stopped"
|
||||||
|
e.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) downloadMetadataFromPeers(ctx context.Context, infoHash [20]byte, name string, peersCh <-chan []PeerStatus, initialPeers []PeerStatus) (*torrentfile.TorrentFile, error) {
|
func (e *Engine) downloadMetadataFromPeers(ctx context.Context, infoHash [20]byte, name string, peersCh <-chan []PeerStatus, initialPeers []PeerStatus) (*torrentfile.TorrentFile, error) {
|
||||||
|
|
@ -603,7 +641,10 @@ func (e *Engine) Status() Status {
|
||||||
status.TotalBytes = int64(e.torrent.Length)
|
status.TotalBytes = int64(e.torrent.Length)
|
||||||
status.PieceLength = e.torrent.PieceLength
|
status.PieceLength = e.torrent.PieceLength
|
||||||
status.PieceCount = len(e.torrent.PieceHashes)
|
status.PieceCount = len(e.torrent.PieceHashes)
|
||||||
status.Files = append(status.Files, e.torrent.Files...)
|
|
||||||
|
status.Files = make([]torrentfile.File, len(e.torrent.Files))
|
||||||
|
copy(status.Files, e.torrent.Files)
|
||||||
|
|
||||||
status.Announce = e.torrent.Announce
|
status.Announce = e.torrent.Announce
|
||||||
}
|
}
|
||||||
if e.lastErr != nil {
|
if e.lastErr != nil {
|
||||||
|
|
|
||||||
1
multi.torrent
Normal file
1
multi.torrent
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
d8:announce30:http://localhost:8000/announce4:infod5:filesld6:lengthi100e4:pathl9:file1.txteed6:lengthi200e4:pathl9:file2.txteee4:name7:testdir12:piece lengthi16384e6:pieces20:12345678901234567890ee
|
||||||
9
ui/ui.go
9
ui/ui.go
|
|
@ -637,11 +637,12 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
|
|
||||||
case key.Matches(msg, keys.PauseResume):
|
case key.Matches(msg, keys.PauseResume):
|
||||||
phase := m.status.Phase
|
phase := m.status.Phase
|
||||||
if phase == "stopped" || phase == "failed" || phase == "" {
|
if phase == "stopped" || phase == "failed" {
|
||||||
m.loadingMetadata = true
|
m.controller.StartTorrentDownload()
|
||||||
return m, tea.Batch(m.spinner.Tick, startTorrentCmd(m.controller, m.torrentPath, m.outputDir, m.inputs[2].Value()))
|
return m, nil
|
||||||
}
|
} else if phase != "" {
|
||||||
m.controller.StopTorrent()
|
m.controller.StopTorrent()
|
||||||
|
}
|
||||||
case key.Matches(msg, keys.OpenNew):
|
case key.Matches(msg, keys.OpenNew):
|
||||||
m.controller.StopTorrent()
|
m.controller.StopTorrent()
|
||||||
m.mainMenuMode = true
|
m.mainMenuMode = true
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue