fix: panic on resume and pause download before starting to allow file priority selection

This commit is contained in:
itexpert228 2026-07-20 19:07:13 +03:00
parent 368bc27eaa
commit 264d73cdc5
5 changed files with 55 additions and 7 deletions

1
dummy.torrent Normal file
View file

@ -0,0 +1 @@
d8:announce15:http://a.b.c/tr13:creation datei1e4:infod6:lengthi100e4:name9:dummy.txt12:piece lengthi16384e6:pieces20:12345678901234567890ee

View file

@ -65,6 +65,10 @@ func (c *Controller) StartTorrent(path, outputRoot string) error {
return nil
}
func (c *Controller) StartTorrentDownload() {
c.engine.StartDownload()
}
func (c *Controller) DownloadMagnet(magnetURI string) error {
cfg, _ := config.Load()
outDir := "."

View file

@ -47,6 +47,7 @@ type Engine struct {
portManager *portforward.PortManager
cancel context.CancelFunc
downloadCtx context.Context
incomingConns chan net.Conn
@ -345,6 +346,9 @@ func (e *Engine) LoadTorrent(path, outputRoot string) error {
downloadCtx, cancel := context.WithCancel(context.Background())
e.swapCancel(cancel)
e.mu.Lock()
e.downloadCtx = downloadCtx
e.mu.Unlock()
if strings.HasPrefix(path, "magnet:") {
go e.loadMagnet(downloadCtx, path, outputRoot)
@ -360,10 +364,38 @@ func (e *Engine) LoadTorrent(path, outputRoot string) error {
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
}
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) {
ml, err := magnet.Parse(uri)
if err != nil {
@ -423,7 +455,13 @@ func (e *Engine) loadMagnet(ctx context.Context, uri, outputRoot string) {
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) {
@ -603,7 +641,10 @@ func (e *Engine) Status() Status {
status.TotalBytes = int64(e.torrent.Length)
status.PieceLength = e.torrent.PieceLength
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
}
if e.lastErr != nil {

1
multi.torrent Normal file
View 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

View file

@ -637,11 +637,12 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case key.Matches(msg, keys.PauseResume):
phase := m.status.Phase
if phase == "stopped" || phase == "failed" || phase == "" {
m.loadingMetadata = true
return m, tea.Batch(m.spinner.Tick, startTorrentCmd(m.controller, m.torrentPath, m.outputDir, m.inputs[2].Value()))
}
if phase == "stopped" || phase == "failed" {
m.controller.StartTorrentDownload()
return m, nil
} else if phase != "" {
m.controller.StopTorrent()
}
case key.Matches(msg, keys.OpenNew):
m.controller.StopTorrent()
m.mainMenuMode = true