mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-21 14:36:09 +05:00
refactor and update
This commit is contained in:
88
src/server/torr/apihelper.go
Normal file
88
src/server/torr/apihelper.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package torr
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sort"
|
||||
|
||||
"github.com/anacrolix/torrent"
|
||||
"github.com/anacrolix/torrent/metainfo"
|
||||
"server/log"
|
||||
)
|
||||
|
||||
var (
|
||||
bts *BTServer
|
||||
)
|
||||
|
||||
func InitApiHelper(bt *BTServer) {
|
||||
bts = bt
|
||||
}
|
||||
|
||||
func AddTorrent(spec *torrent.TorrentSpec, title, poster string) (*Torrent, error) {
|
||||
torr, err := NewTorrent(spec, bts)
|
||||
if err != nil {
|
||||
log.TLogln("error add torrent:", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !torr.GotInfo() {
|
||||
log.TLogln("error add torrent:", "timeout connection torrent")
|
||||
return nil, errors.New("timeout connection torrent")
|
||||
}
|
||||
|
||||
torr.Title = title
|
||||
torr.Poster = poster
|
||||
|
||||
if torr.Title == "" {
|
||||
torr.Title = torr.Name()
|
||||
}
|
||||
|
||||
return torr, nil
|
||||
}
|
||||
|
||||
func SaveTorrentToDB(torr *Torrent) {
|
||||
log.TLogln("save to db:", torr.Hash())
|
||||
AddTorrentDB(torr)
|
||||
}
|
||||
|
||||
func GetTorrent(hashHex string) *Torrent {
|
||||
hash := metainfo.NewHashFromHex(hashHex)
|
||||
tor := bts.GetTorrent(hash)
|
||||
if tor == nil {
|
||||
tor = GetTorrentDB(hash)
|
||||
}
|
||||
|
||||
return tor
|
||||
}
|
||||
|
||||
func RemTorrent(hashHex string) {
|
||||
hash := metainfo.NewHashFromHex(hashHex)
|
||||
bts.RemoveTorrent(hash)
|
||||
RemTorrentDB(hash)
|
||||
}
|
||||
|
||||
func ListTorrent() []*Torrent {
|
||||
btlist := bts.ListTorrents()
|
||||
dblist := ListTorrentsDB()
|
||||
|
||||
for hash, t := range dblist {
|
||||
if _, ok := btlist[hash]; !ok {
|
||||
btlist[hash] = t
|
||||
}
|
||||
}
|
||||
var ret []*Torrent
|
||||
|
||||
for _, t := range btlist {
|
||||
ret = append(ret, t)
|
||||
}
|
||||
|
||||
sort.Slice(ret, func(i, j int) bool {
|
||||
return ret[i].Timestamp > ret[j].Timestamp
|
||||
})
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func DropTorrent(hashHex string) {
|
||||
hash := metainfo.NewHashFromHex(hashHex)
|
||||
bts.RemoveTorrent(hash)
|
||||
}
|
||||
@@ -36,6 +36,7 @@ func (bt *BTServer) Connect() error {
|
||||
bt.configure()
|
||||
bt.client, err = torrent.NewClient(bt.config)
|
||||
bt.torrents = make(map[metainfo.Hash]*Torrent)
|
||||
InitApiHelper(bt)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -109,10 +110,10 @@ func (bt *BTServer) GetTorrent(hash torrent.InfoHash) *Torrent {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bt *BTServer) ListTorrents() []*Torrent {
|
||||
var list []*Torrent
|
||||
for _, t := range bt.torrents {
|
||||
list = append(list, t)
|
||||
func (bt *BTServer) ListTorrents() map[metainfo.Hash]*Torrent {
|
||||
list := make(map[metainfo.Hash]*Torrent)
|
||||
for k, v := range bt.torrents {
|
||||
list[k] = v
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
54
src/server/torr/dbwrapper.go
Normal file
54
src/server/torr/dbwrapper.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package torr
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"server/settings"
|
||||
"server/torr/state"
|
||||
|
||||
"github.com/anacrolix/torrent/metainfo"
|
||||
)
|
||||
|
||||
func AddTorrentDB(torr *Torrent) {
|
||||
t := new(settings.TorrentDB)
|
||||
t.TorrentSpec = torr.TorrentSpec
|
||||
t.Name = torr.Name()
|
||||
t.Title = torr.Title
|
||||
t.Poster = torr.Poster
|
||||
t.Timestamp = time.Now().Unix()
|
||||
t.Files = torr.Status().FileStats
|
||||
settings.AddTorrent(t)
|
||||
}
|
||||
|
||||
func GetTorrentDB(hash metainfo.Hash) *Torrent {
|
||||
list := settings.ListTorrent()
|
||||
for _, db := range list {
|
||||
if hash == db.InfoHash {
|
||||
torr := new(Torrent)
|
||||
torr.TorrentSpec = db.TorrentSpec
|
||||
torr.Title = db.Title
|
||||
torr.Poster = db.Poster
|
||||
torr.Stat = state.TorrentInDB
|
||||
return torr
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RemTorrentDB(hash metainfo.Hash) {
|
||||
settings.RemTorrent(hash)
|
||||
}
|
||||
|
||||
func ListTorrentsDB() map[metainfo.Hash]*Torrent {
|
||||
ret := make(map[metainfo.Hash]*Torrent)
|
||||
list := settings.ListTorrent()
|
||||
for _, db := range list {
|
||||
torr := new(Torrent)
|
||||
torr.TorrentSpec = db.TorrentSpec
|
||||
torr.Title = db.Title
|
||||
torr.Poster = db.Poster
|
||||
torr.Stat = state.TorrentInDB
|
||||
ret[torr.TorrentSpec.InfoHash] = torr
|
||||
}
|
||||
return ret
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package state
|
||||
|
||||
type TorrentStatus int
|
||||
type TorrentStat int
|
||||
|
||||
func (t TorrentStatus) String() string {
|
||||
func (t TorrentStat) String() string {
|
||||
switch t {
|
||||
case TorrentAdded:
|
||||
return "Torrent added"
|
||||
@@ -22,7 +22,7 @@ func (t TorrentStatus) String() string {
|
||||
}
|
||||
|
||||
const (
|
||||
TorrentAdded = TorrentStatus(iota)
|
||||
TorrentAdded = TorrentStat(iota)
|
||||
TorrentGettingInfo
|
||||
TorrentPreload
|
||||
TorrentWorking
|
||||
@@ -30,15 +30,16 @@ const (
|
||||
TorrentInDB
|
||||
)
|
||||
|
||||
type TorrentStats struct {
|
||||
Title string `json:"title"`
|
||||
Poster string `json:"poster"`
|
||||
type TorrentStatus struct {
|
||||
Title string `json:"title"`
|
||||
Poster string `json:"poster"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
|
||||
Name string `json:"name,omitempty"`
|
||||
Hash string `json:"hash,omitempty"`
|
||||
|
||||
TorrentStatus TorrentStatus `json:"torrent_status,omitempty"`
|
||||
TorrentStatusString string `json:"torrent_status_string,omitempty"`
|
||||
Stat TorrentStat `json:"stat"`
|
||||
StatString string `json:"stat_string"`
|
||||
|
||||
LoadedSize int64 `json:"loaded_size,omitempty"`
|
||||
TorrentSize int64 `json:"torrent_size,omitempty"`
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/anacrolix/missinggo/httptoo"
|
||||
sets "server/settings"
|
||||
)
|
||||
|
||||
func (t *Torrent) Stream(fileIndex int, req *http.Request, resp http.ResponseWriter) error {
|
||||
@@ -20,6 +21,8 @@ func (t *Torrent) Stream(fileIndex int, req *http.Request, resp http.ResponseWri
|
||||
|
||||
log.Println("Connect client")
|
||||
|
||||
sets.SetViewed(&sets.Viewed{t.Hash().HexString(), fileIndex})
|
||||
|
||||
resp.Header().Set("Connection", "close")
|
||||
resp.Header().Set("ETag", httptoo.EncodeQuotedString(fmt.Sprintf("%s/%s", t.Hash().HexString(), file.Path())))
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ type Torrent struct {
|
||||
Poster string
|
||||
*torrent.TorrentSpec
|
||||
|
||||
Status state.TorrentStatus
|
||||
Stat state.TorrentStat
|
||||
Timestamp int64
|
||||
/////
|
||||
|
||||
*torrent.Torrent
|
||||
@@ -50,7 +51,6 @@ type Torrent struct {
|
||||
}
|
||||
|
||||
func NewTorrent(spec *torrent.TorrentSpec, bt *BTServer) (*Torrent, error) {
|
||||
|
||||
switch settings.BTsets.RetrackersMode {
|
||||
case 1:
|
||||
spec.Trackers = append(spec.Trackers, [][]string{utils.GetDefTrackers()}...)
|
||||
@@ -73,12 +73,13 @@ func NewTorrent(spec *torrent.TorrentSpec, bt *BTServer) (*Torrent, error) {
|
||||
|
||||
torr := new(Torrent)
|
||||
torr.Torrent = goTorrent
|
||||
torr.Status = state.TorrentAdded
|
||||
torr.Stat = state.TorrentAdded
|
||||
torr.lastTimeSpeed = time.Now()
|
||||
torr.bt = bt
|
||||
torr.closed = goTorrent.Closed()
|
||||
torr.TorrentSpec = spec
|
||||
torr.expiredTime = time.Now().Add(time.Minute)
|
||||
torr.Timestamp = time.Now().Unix()
|
||||
|
||||
go torr.watch()
|
||||
|
||||
@@ -106,12 +107,12 @@ func (t *Torrent) WaitInfo() bool {
|
||||
}
|
||||
|
||||
func (t *Torrent) GotInfo() bool {
|
||||
if t.Status == state.TorrentClosed {
|
||||
if t.Stat == state.TorrentClosed {
|
||||
return false
|
||||
}
|
||||
t.Status = state.TorrentGettingInfo
|
||||
t.Stat = state.TorrentGettingInfo
|
||||
if t.WaitInfo() {
|
||||
t.Status = state.TorrentWorking
|
||||
t.Stat = state.TorrentWorking
|
||||
t.expiredTime = time.Now().Add(time.Minute * 5)
|
||||
return true
|
||||
} else {
|
||||
@@ -179,7 +180,7 @@ func (t *Torrent) updateRA() {
|
||||
}
|
||||
|
||||
func (t *Torrent) expired() bool {
|
||||
return t.cache.ReadersLen() == 0 && t.expiredTime.Before(time.Now()) && (t.Status == state.TorrentWorking || t.Status == state.TorrentClosed)
|
||||
return t.cache.ReadersLen() == 0 && t.expiredTime.Before(time.Now()) && (t.Stat == state.TorrentWorking || t.Stat == state.TorrentClosed)
|
||||
}
|
||||
|
||||
func (t *Torrent) Files() []*torrent.File {
|
||||
@@ -208,7 +209,7 @@ func (t *Torrent) Length() int64 {
|
||||
}
|
||||
|
||||
func (t *Torrent) NewReader(file *torrent.File, readahead int64) *Reader {
|
||||
if t.Status == state.TorrentClosed {
|
||||
if t.Stat == state.TorrentClosed {
|
||||
return nil
|
||||
}
|
||||
reader := NewReader(t, file, readahead)
|
||||
@@ -230,14 +231,14 @@ func (t *Torrent) Preload(index int, size int64) {
|
||||
return
|
||||
}
|
||||
|
||||
if t.Status == state.TorrentGettingInfo {
|
||||
if t.Stat == state.TorrentGettingInfo {
|
||||
t.WaitInfo()
|
||||
// wait change status
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
t.muTorrent.Lock()
|
||||
if t.Status != state.TorrentWorking {
|
||||
if t.Stat != state.TorrentWorking {
|
||||
t.muTorrent.Unlock()
|
||||
return
|
||||
}
|
||||
@@ -249,12 +250,12 @@ func (t *Torrent) Preload(index int, size int64) {
|
||||
t.muTorrent.Unlock()
|
||||
return
|
||||
}
|
||||
t.Status = state.TorrentPreload
|
||||
t.Stat = state.TorrentPreload
|
||||
t.muTorrent.Unlock()
|
||||
|
||||
defer func() {
|
||||
if t.Status == state.TorrentPreload {
|
||||
t.Status = state.TorrentWorking
|
||||
if t.Stat == state.TorrentPreload {
|
||||
t.Stat = state.TorrentWorking
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -299,7 +300,7 @@ func (t *Torrent) Preload(index int, size int64) {
|
||||
t.PreloadSize = size
|
||||
var lastSize int64 = 0
|
||||
errCount := 0
|
||||
for t.Status == state.TorrentPreload {
|
||||
for t.Stat == state.TorrentPreload {
|
||||
t.expiredTime = time.Now().Add(time.Minute * 5)
|
||||
t.PreloadedBytes = t.Torrent.BytesCompleted()
|
||||
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)
|
||||
@@ -330,7 +331,7 @@ func (t *Torrent) drop() {
|
||||
}
|
||||
|
||||
func (t *Torrent) Close() {
|
||||
t.Status = state.TorrentClosed
|
||||
t.Stat = state.TorrentClosed
|
||||
t.bt.mu.Lock()
|
||||
defer t.bt.mu.Unlock()
|
||||
|
||||
@@ -341,16 +342,17 @@ func (t *Torrent) Close() {
|
||||
t.drop()
|
||||
}
|
||||
|
||||
func (t *Torrent) Stats() *state.TorrentStats {
|
||||
func (t *Torrent) Status() *state.TorrentStatus {
|
||||
t.muTorrent.Lock()
|
||||
defer t.muTorrent.Unlock()
|
||||
|
||||
st := new(state.TorrentStats)
|
||||
st := new(state.TorrentStatus)
|
||||
|
||||
st.TorrentStatus = t.Status
|
||||
st.TorrentStatusString = t.Status.String()
|
||||
st.Stat = t.Stat
|
||||
st.StatString = t.Stat.String()
|
||||
st.Title = t.Title
|
||||
st.Poster = t.Poster
|
||||
st.Timestamp = t.Timestamp
|
||||
|
||||
if t.TorrentSpec != nil {
|
||||
st.Hash = t.TorrentSpec.InfoHash.HexString()
|
||||
|
||||
Reference in New Issue
Block a user