From a5c1d5b4de2ee5b804ac2ae5dfd58bff30e6a05b Mon Sep 17 00:00:00 2001 From: YouROK <8yourok8@mail.ru> Date: Mon, 7 Dec 2020 15:55:54 +0300 Subject: [PATCH] add cache --- src/server/torr/state/state.go | 2 +- src/server/torr/storage/state/state.go | 18 ++++++++ src/server/torr/storage/torrstor/cache.go | 35 +++++++++++++++- src/server/torr/torrent.go | 38 +++++++++++++++-- src/server/utils/filetypes.go | 4 +- src/server/web/api/cache.go | 51 +++++++++++++++++++++++ src/server/web/api/route.go | 2 + 7 files changed, 142 insertions(+), 8 deletions(-) create mode 100644 src/server/torr/storage/state/state.go create mode 100644 src/server/web/api/cache.go diff --git a/src/server/torr/state/state.go b/src/server/torr/state/state.go index f4551b6..b4ea083 100644 --- a/src/server/torr/state/state.go +++ b/src/server/torr/state/state.go @@ -61,7 +61,7 @@ type TorrentStatus struct { PiecesDirtiedGood int64 `json:"pieces_dirtied_good,omitempty"` PiecesDirtiedBad int64 `json:"pieces_dirtied_bad,omitempty"` - FileStats []TorrentFileStat `json:"file_stats,omitempty"` + FileStats []*TorrentFileStat `json:"file_stats,omitempty"` } type TorrentFileStat struct { diff --git a/src/server/torr/storage/state/state.go b/src/server/torr/storage/state/state.go new file mode 100644 index 0000000..2c4dbd5 --- /dev/null +++ b/src/server/torr/storage/state/state.go @@ -0,0 +1,18 @@ +package state + +type CacheState struct { + Hash string + Capacity int64 + Filled int64 + PiecesLength int64 + PiecesCount int + DownloadSpeed float64 + Pieces map[int]ItemState +} + +type ItemState struct { + Id int + Length int64 + Size int64 + Completed bool +} diff --git a/src/server/torr/storage/torrstor/cache.go b/src/server/torr/storage/torrstor/cache.go index 9a5a581..957823b 100644 --- a/src/server/torr/storage/torrstor/cache.go +++ b/src/server/torr/storage/torrstor/cache.go @@ -6,6 +6,7 @@ import ( "server/log" "server/settings" + "server/torr/storage/state" "server/torr/utils" "github.com/anacrolix/torrent" @@ -53,7 +54,7 @@ func NewCache(capacity int64, storage *Storage) *Cache { } func (c *Cache) Init(info *metainfo.Info, hash metainfo.Hash) { - log.TLogln("Create cache for:", info.Name) + log.TLogln("Create cache for:", info.Name, hash.HexString()) if c.capacity == 0 { c.capacity = info.PieceLength * 6 } @@ -204,3 +205,35 @@ func (c *Cache) AdjustRA(readahead int64) { r.SetReadahead(readahead) } } + +func (c *Cache) GetState() *state.CacheState { + cState := new(state.CacheState) + cState.Capacity = c.capacity + cState.PiecesLength = c.pieceLength + cState.PiecesCount = c.pieceCount + cState.Hash = c.hash.HexString() + + stats := make(map[int]state.ItemState, 0) + c.muPiece.Lock() + var fill int64 = 0 + for _, p := range c.pieces { + if p.Size > 0 { + fill += p.Length + stats[p.Id] = state.ItemState{ + Id: p.Id, + Size: p.Size, + Length: p.Length, + Completed: p.complete, + } + } + } + c.filled = fill + c.muPiece.Unlock() + cState.Filled = c.filled + cState.Pieces = stats + return cState +} + +func (c *Cache) GetCapacity() int64 { + return c.capacity +} diff --git a/src/server/torr/torrent.go b/src/server/torr/torrent.go index cda9196..e42fc4d 100644 --- a/src/server/torr/torrent.go +++ b/src/server/torr/torrent.go @@ -9,6 +9,7 @@ import ( "server/log" "server/settings" "server/torr/state" + cacheSt "server/torr/storage/state" "server/torr/utils" utils2 "server/utils" @@ -258,10 +259,10 @@ func (t *Torrent) Preload(index int, size int64) { } }() - if index < 0 || index >= len(t.Files()) { - index = 0 + file := t.findFileIndex(index) + if file == nil { + file = t.Files()[0] } - file := t.Files()[index] buff5mb := int64(5 * 1024 * 1024) startPreloadLength := size @@ -393,7 +394,7 @@ func (t *Torrent) Status() *state.TorrentStatus { return files[i].Path() < files[j].Path() }) for i, f := range files { - st.FileStats = append(st.FileStats, state.TorrentFileStat{ + st.FileStats = append(st.FileStats, &state.TorrentFileStat{ Id: i + 1, Path: f.Path(), Length: f.Length(), @@ -403,3 +404,32 @@ func (t *Torrent) Status() *state.TorrentStatus { } return st } + +func (t *Torrent) CacheState() *cacheSt.CacheState { + if t.Torrent != nil && t.cache != nil { + st := t.cache.GetState() + st.DownloadSpeed = t.DownloadSpeed + return st + } + return nil +} + +func (t *Torrent) findFileIndex(index int) *torrent.File { + st := t.Status() + var stFile *state.TorrentFileStat + for _, f := range st.FileStats { + if index == f.Id { + stFile = f + break + } + } + if stFile == nil { + return nil + } + for _, file := range t.Files() { + if file.Path() == stFile.Path { + return file + } + } + return nil +} diff --git a/src/server/utils/filetypes.go b/src/server/utils/filetypes.go index f7e41e8..1ce8445 100644 --- a/src/server/utils/filetypes.go +++ b/src/server/utils/filetypes.go @@ -78,8 +78,8 @@ func GetMimeType(filename string) string { return "*/*" } -func GetPlayableFiles(st state.TorrentStatus) []state.TorrentFileStat { - files := make([]state.TorrentFileStat, 0) +func GetPlayableFiles(st state.TorrentStatus) []*state.TorrentFileStat { + files := make([]*state.TorrentFileStat, 0) for _, f := range st.FileStats { if GetMimeType(f.Path) != "*/*" { files = append(files, f) diff --git a/src/server/web/api/cache.go b/src/server/web/api/cache.go new file mode 100644 index 0000000..e8da18b --- /dev/null +++ b/src/server/web/api/cache.go @@ -0,0 +1,51 @@ +package api + +import ( + "net/http" + + "server/torr" + + "github.com/gin-gonic/gin" + "github.com/pkg/errors" +) + +//Action: get +type cacheReqJS struct { + requestI + Hash string `json:"hash,omitempty"` +} + +func cache(c *gin.Context) { + var req cacheReqJS + err := c.ShouldBindJSON(&req) + if err != nil { + c.AbortWithError(http.StatusBadRequest, err) + return + } + c.Status(http.StatusBadRequest) + switch req.Action { + case "get": + { + getCache(req, c) + } + } +} + +func getCache(req cacheReqJS, c *gin.Context) { + if req.Hash == "" { + c.AbortWithError(http.StatusBadRequest, errors.New("hash is empty")) + return + } + tor := torr.GetTorrent(req.Hash) + + if tor != nil { + st := tor.CacheState() + if st == nil { + c.JSON(200, struct{}{}) + } else { + c.JSON(200, st) + } + } else { + c.Status(http.StatusNotFound) + } +} diff --git a/src/server/web/api/route.go b/src/server/web/api/route.go index 03b0e6a..098dd1a 100644 --- a/src/server/web/api/route.go +++ b/src/server/web/api/route.go @@ -23,6 +23,8 @@ func SetupRoute(route *gin.Engine) { route.POST("/torrents", torrents) route.POST("/torrent/upload", torrentUpload) + route.POST("/cache", cache) + route.GET("/stream", stream) route.GET("/stream/*fname", stream)