From ed0f8b5c2103a5d34d8e69106252bdf79f5db85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D1=80=D0=BE=D0=B4=D0=B8=D0=BD=20=D0=A0=D0=BE?= =?UTF-8?q?=D0=BC=D0=B0=D0=BD?= Date: Fri, 25 Mar 2022 01:27:42 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D0=B0=D1=8F=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F?= =?UTF-8?q?=20=D0=BD=D0=B0=20=D1=80=D0=B0=D0=B7=D0=BD=D1=8B=D1=85=20=D0=B0?= =?UTF-8?q?=D1=80=D1=85=D0=B8=D1=82=D0=B5=D0=BA=D1=82=D1=83=D1=80=D0=B0?= =?UTF-8?q?=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- engine.go | 63 +++++++++++++++++++++++++++--------------------------- go.mod | 3 ++- gorrent.go | 2 ++ 3 files changed, 36 insertions(+), 32 deletions(-) diff --git a/engine.go b/engine.go index 2002ea1..2656640 100644 --- a/engine.go +++ b/engine.go @@ -10,12 +10,13 @@ import ( "net/url" "os" "path" + "strconv" "strings" "sync" "time" ) -const boltDbDir = `piece_complete_db` +const refreshSec = 3 type TorrentStatus struct { DownloadRate int64 @@ -48,6 +49,7 @@ type Engine struct { upRate int64 seeds int64 } + fs FileStatus } func (o *Engine) IsAlive() bool { @@ -60,6 +62,7 @@ func (o *Engine) StartTorrent(idx int64) error { o.torrCfg.ListenPort = o.settings.ListenPort o.torrCfg.DataDir = o.settings.DownloadPath o.torrCfg.DefaultStorage = storage.NewFileWithCompletion(o.settings.DownloadPath, storage.NewMapPieceCompletion()) + if o.settings.Proxy != "" { if u, err := url.Parse(o.settings.Proxy); err != nil { o.torrCfg.HTTPProxy = func(request *http.Request) (*url.URL, error) { return u, nil } @@ -82,6 +85,8 @@ func (o *Engine) StartTorrent(idx int64) error { t := o.torrent <-t.GotInfo() + o.setStaticFileStatusData(idx) + file := o.torrent.Files()[idx] // отключаем загрузку всех файлов @@ -92,12 +97,8 @@ func (o *Engine) StartTorrent(idx int64) error { endPieceIndex := (file.Offset() + file.Length()) * int64(t.NumPieces()) / t.Length() o.torrent.DownloadPieces(int(firstPieceIndex), int(endPieceIndex)) - for i := firstPieceIndex; i <= endPieceIndex*5/100; i++ { - t.Piece(int(i)).SetPriority(torrent.PiecePriorityNow) - } - go func() { - ticker := time.NewTicker(time.Second) + ticker := time.NewTicker(time.Second * refreshSec) defer ticker.Stop() for { select { @@ -131,18 +132,34 @@ func (o *Engine) StartTorrent(idx int64) error { return nil } +func (o *Engine) setStaticFileStatusData(i int64) { + o.fs = FileStatus{} + file := o.torrent.Files()[i] + + pathParts := strings.Split(file.DisplayPath(), `/`) + o.fs.Name = file.DisplayPath() + for idx := range pathParts { + pathParts[idx] = url.QueryEscape(pathParts[idx]) + } + o.fs.Url = fmt.Sprintf(`http://%s:%d/files/%s`, o.settings.HttpBindHost, o.settings.HttpBindPort, strings.Join(pathParts, `/`)) + o.fs.Length = file.Length() + if o.fs.Length < 0 { + o.fs.Length *= -1 + } +} + func (o *Engine) updateStats() { stats := o.torrent.Stats() if o.status.lastBytesReadData == 0 { o.status.downRate = 0 } else { - o.status.downRate = (stats.BytesReadData.Int64() - o.status.lastBytesReadData) / 1024 + o.status.downRate = (stats.BytesReadData.Int64() - o.status.lastBytesReadData) / 1024 / refreshSec } o.status.lastBytesReadData = stats.BytesReadData.Int64() if o.status.lastBytesWrittenData == 0 { o.status.upRate = 0 } else { - o.status.upRate = (stats.BytesWrittenData.Int64() - o.status.lastBytesWrittenData) / 1024 + o.status.upRate = (stats.BytesWrittenData.Int64() - o.status.lastBytesWrittenData) / 1024 / refreshSec } o.status.lastBytesWrittenData = stats.BytesWrittenData.Int64() o.status.seeds = int64(stats.ConnectedSeeders) @@ -156,28 +173,15 @@ func (o *Engine) Status() TorrentStatus { return res } func (o *Engine) FileStatus(i int) (FileStatus, error) { - fs := FileStatus{} if i < 0 || i > len(o.torrent.Files())-1 { - return fs, fmt.Errorf(`file index out of range: %d`, i) + return o.fs, fmt.Errorf(`file index out of range: %d`, i) } - file := o.torrent.Files()[i] - - pathParts := strings.Split(file.DisplayPath(), `/`) - fs.Name = file.DisplayPath() - for idx := range pathParts { - pathParts[idx] = url.QueryEscape(pathParts[idx]) + o.fs.Progress = int64(float64(file.BytesCompleted()) / float64(file.Length()) * 100.0) + if o.fs.Progress < 0 { + o.fs.Progress *= -1 } - fs.Url = fmt.Sprintf(`http://%s:%d/files/%s`, o.settings.HttpBindHost, o.settings.HttpBindPort, strings.Join(pathParts, `/`)) - fs.Progress = int64(float64(file.BytesCompleted()) / float64(file.Length()) * 100.0) - if fs.Progress < 0 { - fs.Progress *= -1 - } - fs.Length = file.Length() - if fs.Length < 0 { - fs.Length *= -1 - } - return fs, nil + return o.fs, nil } func (o *Engine) Stop() { @@ -201,6 +205,7 @@ func (o *Engine) Stop() { } o.syncDebug(`torrent engine stopped`) + o.shutdown() close(o.msgs) o.alive = false }() @@ -276,8 +281,6 @@ func (o *Engine) syncInfo(t string, a ...interface{}) { func (o *Engine) GetFileHandler(target *torrent.File) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { entry := target.NewReader() - entry.SetReadahead(target.Length() / 100) - entry.SetResponsive() defer func() { if err := entry.Close(); err != nil { @@ -285,9 +288,7 @@ func (o *Engine) GetFileHandler(target *torrent.File) func(http.ResponseWriter, } }() - pathParts := strings.Split(target.DisplayPath(), `/`) - - w.Header().Set("Content-Disposition", "attachment; filename=\""+pathParts[len(pathParts)-1]+"\"") + w.Header().Set("Content-Disposition", "attachment; filename="+strconv.Quote(target.DisplayPath())) http.ServeContent(w, r, target.DisplayPath(), time.Now(), entry) } } diff --git a/go.mod b/go.mod index 5931595..0a7c832 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module gorrent go 1.17 require ( + github.com/anacrolix/missinggo/v2 v2.5.2 github.com/anacrolix/torrent v1.41.0 github.com/go-python/gopy v0.4.0 golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd @@ -18,7 +19,6 @@ require ( github.com/anacrolix/log v0.10.1-0.20220123034749-3920702c17f8 // indirect github.com/anacrolix/missinggo v1.3.0 // indirect github.com/anacrolix/missinggo/perf v1.0.0 // indirect - github.com/anacrolix/missinggo/v2 v2.5.2 // indirect github.com/anacrolix/mmsg v1.0.0 // indirect github.com/anacrolix/multiless v0.2.0 // indirect github.com/anacrolix/stm v0.3.0 // indirect @@ -57,6 +57,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect github.com/rs/dnscache v0.0.0-20210201191234-295bba877686 // indirect + github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 // indirect go.etcd.io/bbolt v1.3.6 // indirect golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect diff --git a/gorrent.go b/gorrent.go index a2a65d6..c3fedf4 100644 --- a/gorrent.go +++ b/gorrent.go @@ -4,6 +4,8 @@ import "context" var version = `1.0.0` +const defaultMaxReadaheadBytes = 20 * 1024 * 1024 + func GetMetaFromFile(path string) (*Info, error) { info := &Info{} if err := info.LoadFile(path); err != nil {