Проверенная версия на разных архитектурах

master v1.1.0
Роман Бородин 2022-03-25 01:27:42 +03:00
parent afe5f9a232
commit ed0f8b5c21
3 changed files with 36 additions and 32 deletions

View File

@ -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)
}
}

3
go.mod
View File

@ -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

View File

@ -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 {