mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-21 14:36:09 +05:00
update
This commit is contained in:
@@ -83,6 +83,9 @@ func (bt *BTServer) configure() {
|
||||
bt.config.HTTPUserAgent = userAgent
|
||||
bt.config.ExtendedHandshakeClientVersion = cliVers
|
||||
bt.config.EstablishedConnsPerTorrent = settings.BTsets.ConnectionsLimit
|
||||
|
||||
bt.config.DefaultRequestStrategy = torrent.RequestStrategyFastest()
|
||||
|
||||
if settings.BTsets.DhtConnectionLimit > 0 {
|
||||
bt.config.ConnTracker.SetMaxEntries(settings.BTsets.DhtConnectionLimit)
|
||||
}
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
package torr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/anacrolix/torrent"
|
||||
)
|
||||
|
||||
type BTState struct {
|
||||
LocalPort int
|
||||
PeerID string
|
||||
BannedIPs int
|
||||
DHTs []torrent.DhtServer
|
||||
|
||||
Torrents []*Torrent
|
||||
}
|
||||
|
||||
func (bt *BTServer) BTState() *BTState {
|
||||
bt.mu.Lock()
|
||||
defer bt.mu.Unlock()
|
||||
|
||||
btState := new(BTState)
|
||||
btState.LocalPort = bt.client.LocalPort()
|
||||
btState.PeerID = fmt.Sprintf("%x", bt.client.PeerID())
|
||||
btState.BannedIPs = len(bt.client.BadPeerIPs())
|
||||
btState.DHTs = bt.client.DhtServers()
|
||||
|
||||
for _, t := range bt.torrents {
|
||||
btState.Torrents = append(btState.Torrents, t)
|
||||
}
|
||||
return btState
|
||||
}
|
||||
|
||||
type TorrentStats struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Hash string `json:"hash,omitempty"`
|
||||
|
||||
TorrentStatus TorrentStatus `json:"torrent_status,omitempty"`
|
||||
TorrentStatusString string `json:"torrent_status_string,omitempty"`
|
||||
|
||||
LoadedSize int64 `json:"loaded_size,omitempty"`
|
||||
TorrentSize int64 `json:"torrent_size,omitempty"`
|
||||
|
||||
PreloadedBytes int64 `json:"preloaded_bytes,omitempty"`
|
||||
PreloadSize int64 `json:"preload_size,omitempty"`
|
||||
|
||||
DownloadSpeed float64 `json:"download_speed,omitempty"`
|
||||
UploadSpeed float64 `json:"upload_speed,omitempty"`
|
||||
|
||||
TotalPeers int `json:"total_peers,omitempty"`
|
||||
PendingPeers int `json:"pending_peers,omitempty"`
|
||||
ActivePeers int `json:"active_peers,omitempty"`
|
||||
ConnectedSeeders int `json:"connected_seeders,omitempty"`
|
||||
HalfOpenPeers int `json:"half_open_peers,omitempty"`
|
||||
|
||||
BytesWritten int64 `json:"bytes_written,omitempty"`
|
||||
BytesWrittenData int64 `json:"bytes_written_data,omitempty"`
|
||||
BytesRead int64 `json:"bytes_read,omitempty"`
|
||||
BytesReadData int64 `json:"bytes_read_data,omitempty"`
|
||||
BytesReadUsefulData int64 `json:"bytes_read_useful_data,omitempty"`
|
||||
ChunksWritten int64 `json:"chunks_written,omitempty"`
|
||||
ChunksRead int64 `json:"chunks_read,omitempty"`
|
||||
ChunksReadUseful int64 `json:"chunks_read_useful,omitempty"`
|
||||
ChunksReadWasted int64 `json:"chunks_read_wasted,omitempty"`
|
||||
PiecesDirtiedGood int64 `json:"pieces_dirtied_good,omitempty"`
|
||||
PiecesDirtiedBad int64 `json:"pieces_dirtied_bad,omitempty"`
|
||||
|
||||
FileStats []TorrentFileStat `json:"file_stats,omitempty"`
|
||||
}
|
||||
|
||||
type TorrentFileStat struct {
|
||||
Id int `json:"id,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
Length int64 `json:"length,omitempty"`
|
||||
}
|
||||
|
||||
func (t *Torrent) Stats() TorrentStats {
|
||||
t.muTorrent.Lock()
|
||||
defer t.muTorrent.Unlock()
|
||||
|
||||
st := TorrentStats{}
|
||||
|
||||
st.Name = t.Name()
|
||||
st.Hash = t.hash.HexString()
|
||||
st.TorrentStatus = t.Status
|
||||
st.TorrentStatusString = t.Status.String()
|
||||
|
||||
if t.Torrent != nil {
|
||||
st.LoadedSize = t.Torrent.BytesCompleted()
|
||||
st.TorrentSize = t.Length()
|
||||
st.PreloadedBytes = t.PreloadedBytes
|
||||
st.PreloadSize = t.PreloadSize
|
||||
st.DownloadSpeed = t.DownloadSpeed
|
||||
st.UploadSpeed = t.UploadSpeed
|
||||
|
||||
tst := t.Torrent.Stats()
|
||||
st.BytesWritten = tst.BytesWritten.Int64()
|
||||
st.BytesWrittenData = tst.BytesWrittenData.Int64()
|
||||
st.BytesRead = tst.BytesRead.Int64()
|
||||
st.BytesReadData = tst.BytesReadData.Int64()
|
||||
st.BytesReadUsefulData = tst.BytesReadUsefulData.Int64()
|
||||
st.ChunksWritten = tst.ChunksWritten.Int64()
|
||||
st.ChunksRead = tst.ChunksRead.Int64()
|
||||
st.ChunksReadUseful = tst.ChunksReadUseful.Int64()
|
||||
st.ChunksReadWasted = tst.ChunksReadWasted.Int64()
|
||||
st.PiecesDirtiedGood = tst.PiecesDirtiedGood.Int64()
|
||||
st.PiecesDirtiedBad = tst.PiecesDirtiedBad.Int64()
|
||||
st.TotalPeers = tst.TotalPeers
|
||||
st.PendingPeers = tst.PendingPeers
|
||||
st.ActivePeers = tst.ActivePeers
|
||||
st.ConnectedSeeders = tst.ConnectedSeeders
|
||||
st.HalfOpenPeers = tst.HalfOpenPeers
|
||||
|
||||
files := t.Files()
|
||||
|
||||
sort.Slice(files, func(i, j int) bool {
|
||||
return files[i].Path() < files[j].Path()
|
||||
})
|
||||
|
||||
for i, f := range files {
|
||||
st.FileStats = append(st.FileStats, TorrentFileStat{
|
||||
Id: i,
|
||||
Path: f.Path(),
|
||||
Length: f.Length(),
|
||||
})
|
||||
}
|
||||
}
|
||||
return st
|
||||
}
|
||||
74
src/server/torr/state/state.go
Normal file
74
src/server/torr/state/state.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package state
|
||||
|
||||
type TorrentStatus int
|
||||
|
||||
func (t TorrentStatus) String() string {
|
||||
switch t {
|
||||
case TorrentAdded:
|
||||
return "Torrent added"
|
||||
case TorrentGettingInfo:
|
||||
return "Torrent getting info"
|
||||
case TorrentPreload:
|
||||
return "Torrent preload"
|
||||
case TorrentWorking:
|
||||
return "Torrent working"
|
||||
case TorrentClosed:
|
||||
return "Torrent closed"
|
||||
case TorrentInDB:
|
||||
return "Torrent in db"
|
||||
default:
|
||||
return "Torrent unknown status"
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
TorrentAdded = TorrentStatus(iota)
|
||||
TorrentGettingInfo
|
||||
TorrentPreload
|
||||
TorrentWorking
|
||||
TorrentClosed
|
||||
TorrentInDB
|
||||
)
|
||||
|
||||
type TorrentStats struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Hash string `json:"hash,omitempty"`
|
||||
|
||||
TorrentStatus TorrentStatus `json:"torrent_status,omitempty"`
|
||||
TorrentStatusString string `json:"torrent_status_string,omitempty"`
|
||||
|
||||
LoadedSize int64 `json:"loaded_size,omitempty"`
|
||||
TorrentSize int64 `json:"torrent_size,omitempty"`
|
||||
|
||||
PreloadedBytes int64 `json:"preloaded_bytes,omitempty"`
|
||||
PreloadSize int64 `json:"preload_size,omitempty"`
|
||||
|
||||
DownloadSpeed float64 `json:"download_speed,omitempty"`
|
||||
UploadSpeed float64 `json:"upload_speed,omitempty"`
|
||||
|
||||
TotalPeers int `json:"total_peers,omitempty"`
|
||||
PendingPeers int `json:"pending_peers,omitempty"`
|
||||
ActivePeers int `json:"active_peers,omitempty"`
|
||||
ConnectedSeeders int `json:"connected_seeders,omitempty"`
|
||||
HalfOpenPeers int `json:"half_open_peers,omitempty"`
|
||||
|
||||
BytesWritten int64 `json:"bytes_written,omitempty"`
|
||||
BytesWrittenData int64 `json:"bytes_written_data,omitempty"`
|
||||
BytesRead int64 `json:"bytes_read,omitempty"`
|
||||
BytesReadData int64 `json:"bytes_read_data,omitempty"`
|
||||
BytesReadUsefulData int64 `json:"bytes_read_useful_data,omitempty"`
|
||||
ChunksWritten int64 `json:"chunks_written,omitempty"`
|
||||
ChunksRead int64 `json:"chunks_read,omitempty"`
|
||||
ChunksReadUseful int64 `json:"chunks_read_useful,omitempty"`
|
||||
ChunksReadWasted int64 `json:"chunks_read_wasted,omitempty"`
|
||||
PiecesDirtiedGood int64 `json:"pieces_dirtied_good,omitempty"`
|
||||
PiecesDirtiedBad int64 `json:"pieces_dirtied_bad,omitempty"`
|
||||
|
||||
FileStats []TorrentFileStat `json:"file_stats,omitempty"`
|
||||
}
|
||||
|
||||
type TorrentFileStat struct {
|
||||
Id int `json:"id,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
Length int64 `json:"length,omitempty"`
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package torrstor
|
||||
|
||||
import (
|
||||
"log"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/anacrolix/torrent"
|
||||
"server/log"
|
||||
"server/settings"
|
||||
"server/torr/utils"
|
||||
|
||||
@@ -52,7 +52,7 @@ func NewCache(capacity int64, storage *Storage) *Cache {
|
||||
}
|
||||
|
||||
func (c *Cache) Init(info *metainfo.Info, hash metainfo.Hash) {
|
||||
log.Println("Create cache for:", info.Name)
|
||||
log.TLogln("Create cache for:", info.Name)
|
||||
if c.capacity == 0 {
|
||||
c.capacity = info.PieceLength * 6
|
||||
}
|
||||
@@ -89,7 +89,7 @@ func (c *Cache) Piece(m metainfo.Piece) storage.PieceImpl {
|
||||
|
||||
func (c *Cache) Close() error {
|
||||
c.isRemove = false
|
||||
log.Println("Close cache for:", c.hash)
|
||||
log.TLogln("Close cache for:", c.hash)
|
||||
if _, ok := c.s.caches[c.hash]; ok {
|
||||
delete(c.s.caches, c.hash)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@ package torr
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"server/log"
|
||||
"server/settings"
|
||||
"server/torr/state"
|
||||
"server/torr/utils"
|
||||
utils2 "server/utils"
|
||||
|
||||
@@ -16,43 +18,13 @@ import (
|
||||
"github.com/anacrolix/torrent/metainfo"
|
||||
)
|
||||
|
||||
type TorrentStatus int
|
||||
|
||||
func (t TorrentStatus) String() string {
|
||||
switch t {
|
||||
case TorrentAdded:
|
||||
return "Torrent added"
|
||||
case TorrentGettingInfo:
|
||||
return "Torrent getting info"
|
||||
case TorrentPreload:
|
||||
return "Torrent preload"
|
||||
case TorrentWorking:
|
||||
return "Torrent working"
|
||||
case TorrentClosed:
|
||||
return "Torrent closed"
|
||||
case TorrentInDB:
|
||||
return "Torrent in db"
|
||||
default:
|
||||
return "Torrent unknown status"
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
TorrentAdded = TorrentStatus(iota)
|
||||
TorrentGettingInfo
|
||||
TorrentPreload
|
||||
TorrentWorking
|
||||
TorrentClosed
|
||||
TorrentInDB
|
||||
)
|
||||
|
||||
type Torrent struct {
|
||||
///// info for db
|
||||
Title string
|
||||
Poster string
|
||||
*torrent.TorrentSpec
|
||||
|
||||
Status TorrentStatus
|
||||
Status state.TorrentStatus
|
||||
/////
|
||||
|
||||
*torrent.Torrent
|
||||
@@ -103,7 +75,7 @@ func NewTorrent(spec *torrent.TorrentSpec, bt *BTServer) (*Torrent, error) {
|
||||
|
||||
torr := new(Torrent)
|
||||
torr.Torrent = goTorrent
|
||||
torr.Status = TorrentAdded
|
||||
torr.Status = state.TorrentAdded
|
||||
torr.lastTimeSpeed = time.Now()
|
||||
torr.bt = bt
|
||||
torr.closed = goTorrent.Closed()
|
||||
@@ -135,12 +107,12 @@ func (t *Torrent) WaitInfo() bool {
|
||||
}
|
||||
|
||||
func (t *Torrent) GotInfo() bool {
|
||||
if t.Status == TorrentClosed {
|
||||
if t.Status == state.TorrentClosed {
|
||||
return false
|
||||
}
|
||||
t.Status = TorrentGettingInfo
|
||||
t.Status = state.TorrentGettingInfo
|
||||
if t.WaitInfo() {
|
||||
t.Status = TorrentWorking
|
||||
t.Status = state.TorrentWorking
|
||||
t.expiredTime = time.Now().Add(time.Minute * 5)
|
||||
return true
|
||||
} else {
|
||||
@@ -166,6 +138,7 @@ func (t *Torrent) watch() {
|
||||
|
||||
func (t *Torrent) progressEvent() {
|
||||
if t.expired() {
|
||||
log.TLogln("Torrent close by timeout", t.Torrent.InfoHash().HexString())
|
||||
t.drop()
|
||||
return
|
||||
}
|
||||
@@ -207,7 +180,7 @@ func (t *Torrent) updateRA() {
|
||||
}
|
||||
|
||||
func (t *Torrent) expired() bool {
|
||||
return t.cache.ReadersLen() == 0 && t.expiredTime.Before(time.Now()) && (t.Status == TorrentWorking || t.Status == TorrentClosed)
|
||||
return t.cache.ReadersLen() == 0 && t.expiredTime.Before(time.Now()) && (t.Status == state.TorrentWorking || t.Status == state.TorrentClosed)
|
||||
}
|
||||
|
||||
func (t *Torrent) Files() []*torrent.File {
|
||||
@@ -230,7 +203,7 @@ func (t *Torrent) Length() int64 {
|
||||
}
|
||||
|
||||
func (t *Torrent) NewReader(file *torrent.File, readahead int64) *Reader {
|
||||
if t.Status == TorrentClosed {
|
||||
if t.Status == state.TorrentClosed {
|
||||
return nil
|
||||
}
|
||||
reader := NewReader(t, file, readahead)
|
||||
@@ -252,14 +225,14 @@ func (t *Torrent) Preload(index int, size int64) {
|
||||
return
|
||||
}
|
||||
|
||||
if t.Status == TorrentGettingInfo {
|
||||
if t.Status == state.TorrentGettingInfo {
|
||||
t.WaitInfo()
|
||||
// wait change status
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
t.muTorrent.Lock()
|
||||
if t.Status != TorrentWorking {
|
||||
if t.Status != state.TorrentWorking {
|
||||
t.muTorrent.Unlock()
|
||||
return
|
||||
}
|
||||
@@ -271,12 +244,12 @@ func (t *Torrent) Preload(index int, size int64) {
|
||||
t.muTorrent.Unlock()
|
||||
return
|
||||
}
|
||||
t.Status = TorrentPreload
|
||||
t.Status = state.TorrentPreload
|
||||
t.muTorrent.Unlock()
|
||||
|
||||
defer func() {
|
||||
if t.Status == TorrentPreload {
|
||||
t.Status = TorrentWorking
|
||||
if t.Status == state.TorrentPreload {
|
||||
t.Status = state.TorrentWorking
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -321,10 +294,10 @@ func (t *Torrent) Preload(index int, size int64) {
|
||||
t.PreloadSize = size
|
||||
var lastSize int64 = 0
|
||||
errCount := 0
|
||||
for t.Status == TorrentPreload {
|
||||
for t.Status == state.TorrentPreload {
|
||||
t.expiredTime = time.Now().Add(time.Minute * 5)
|
||||
t.PreloadedBytes = t.Torrent.BytesCompleted()
|
||||
log.Println("Preload:", file.Torrent().InfoHash().HexString(), utils2.Format(float64(t.PreloadedBytes)), "/", utils2.Format(float64(t.PreloadSize)), "Speed:", utils2.Format(t.DownloadSpeed), "Peers:[", t.Torrent.Stats().ConnectedSeeders, "]", t.Torrent.Stats().ActivePeers, "/", t.Torrent.Stats().TotalPeers)
|
||||
log.TLogln("Preload:", file.Torrent().InfoHash().HexString(), utils2.Format(float64(t.PreloadedBytes)), "/", utils2.Format(float64(t.PreloadSize)), "Speed:", utils2.Format(t.DownloadSpeed), "Peers:[", t.Torrent.Stats().ConnectedSeeders, "]", t.Torrent.Stats().ActivePeers, "/", t.Torrent.Stats().TotalPeers)
|
||||
if t.PreloadedBytes >= t.PreloadSize {
|
||||
return
|
||||
}
|
||||
@@ -352,7 +325,7 @@ func (t *Torrent) drop() {
|
||||
}
|
||||
|
||||
func (t *Torrent) Close() {
|
||||
t.Status = TorrentClosed
|
||||
t.Status = state.TorrentClosed
|
||||
t.bt.mu.Lock()
|
||||
defer t.bt.mu.Unlock()
|
||||
|
||||
@@ -362,3 +335,59 @@ func (t *Torrent) Close() {
|
||||
|
||||
t.drop()
|
||||
}
|
||||
|
||||
func (t *Torrent) Stats() *state.TorrentStats {
|
||||
t.muTorrent.Lock()
|
||||
defer t.muTorrent.Unlock()
|
||||
|
||||
st := new(state.TorrentStats)
|
||||
|
||||
st.TorrentStatus = t.Status
|
||||
st.TorrentStatusString = t.Status.String()
|
||||
if t.TorrentSpec != nil {
|
||||
st.Hash = t.TorrentSpec.InfoHash.HexString()
|
||||
}
|
||||
if t.Torrent != nil {
|
||||
st.Name = t.Torrent.Name()
|
||||
st.Hash = t.Torrent.InfoHash().HexString()
|
||||
st.LoadedSize = t.Torrent.BytesCompleted()
|
||||
st.TorrentSize = t.Length()
|
||||
st.PreloadedBytes = t.PreloadedBytes
|
||||
st.PreloadSize = t.PreloadSize
|
||||
st.DownloadSpeed = t.DownloadSpeed
|
||||
st.UploadSpeed = t.UploadSpeed
|
||||
|
||||
tst := t.Torrent.Stats()
|
||||
st.BytesWritten = tst.BytesWritten.Int64()
|
||||
st.BytesWrittenData = tst.BytesWrittenData.Int64()
|
||||
st.BytesRead = tst.BytesRead.Int64()
|
||||
st.BytesReadData = tst.BytesReadData.Int64()
|
||||
st.BytesReadUsefulData = tst.BytesReadUsefulData.Int64()
|
||||
st.ChunksWritten = tst.ChunksWritten.Int64()
|
||||
st.ChunksRead = tst.ChunksRead.Int64()
|
||||
st.ChunksReadUseful = tst.ChunksReadUseful.Int64()
|
||||
st.ChunksReadWasted = tst.ChunksReadWasted.Int64()
|
||||
st.PiecesDirtiedGood = tst.PiecesDirtiedGood.Int64()
|
||||
st.PiecesDirtiedBad = tst.PiecesDirtiedBad.Int64()
|
||||
st.TotalPeers = tst.TotalPeers
|
||||
st.PendingPeers = tst.PendingPeers
|
||||
st.ActivePeers = tst.ActivePeers
|
||||
st.ConnectedSeeders = tst.ConnectedSeeders
|
||||
st.HalfOpenPeers = tst.HalfOpenPeers
|
||||
|
||||
files := t.Files()
|
||||
|
||||
sort.Slice(files, func(i, j int) bool {
|
||||
return files[i].Path() < files[j].Path()
|
||||
})
|
||||
|
||||
for i, f := range files {
|
||||
st.FileStats = append(st.FileStats, state.TorrentFileStat{
|
||||
Id: i,
|
||||
Path: f.Path(),
|
||||
Length: f.Length(),
|
||||
})
|
||||
}
|
||||
}
|
||||
return st
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user