2020-11-08 17:19:25 +00:00
|
|
|
package http
|
|
|
|
|
|
|
|
import (
|
2021-11-20 19:57:25 +00:00
|
|
|
"bytes"
|
|
|
|
"io"
|
|
|
|
"math"
|
2020-11-09 10:33:19 +00:00
|
|
|
"net/http"
|
2021-11-20 19:57:25 +00:00
|
|
|
"os"
|
2021-01-02 19:09:05 +00:00
|
|
|
"sort"
|
2020-11-08 17:19:25 +00:00
|
|
|
|
|
|
|
"github.com/anacrolix/missinggo/v2/filecache"
|
2021-11-16 12:13:58 +00:00
|
|
|
"github.com/distribyted/distribyted/torrent"
|
2020-11-08 17:19:25 +00:00
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
)
|
|
|
|
|
2021-11-16 12:13:58 +00:00
|
|
|
var apiStatusHandler = func(fc *filecache.Cache, ss *torrent.Stats) gin.HandlerFunc {
|
2020-11-08 17:19:25 +00:00
|
|
|
return func(ctx *gin.Context) {
|
|
|
|
// TODO move to a struct
|
2020-11-09 10:33:19 +00:00
|
|
|
ctx.JSON(http.StatusOK, gin.H{
|
2020-11-08 17:19:25 +00:00
|
|
|
"cacheItems": fc.Info().NumItems,
|
|
|
|
"cacheFilled": fc.Info().Filled / 1024 / 1024,
|
|
|
|
"cacheCapacity": fc.Info().Capacity / 1024 / 1024,
|
|
|
|
"torrentStats": ss.GlobalStats(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-21 13:03:18 +00:00
|
|
|
var apiServersHandler = func(ss []*torrent.Server) gin.HandlerFunc {
|
|
|
|
return func(ctx *gin.Context) {
|
|
|
|
var infos []*torrent.ServerInfo
|
|
|
|
for _, s := range ss {
|
|
|
|
infos = append(infos, s.Info())
|
|
|
|
}
|
|
|
|
ctx.JSON(http.StatusOK, infos)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-16 12:13:58 +00:00
|
|
|
var apiRoutesHandler = func(ss *torrent.Stats) gin.HandlerFunc {
|
2020-11-08 17:19:25 +00:00
|
|
|
return func(ctx *gin.Context) {
|
2021-01-02 19:09:05 +00:00
|
|
|
s := ss.RoutesStats()
|
2021-11-16 12:13:58 +00:00
|
|
|
sort.Sort(torrent.ByName(s))
|
2021-01-02 19:09:05 +00:00
|
|
|
ctx.JSON(http.StatusOK, s)
|
2020-11-08 17:19:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-16 12:13:58 +00:00
|
|
|
var apiAddTorrentHandler = func(s *torrent.Service) gin.HandlerFunc {
|
2020-11-08 17:19:25 +00:00
|
|
|
return func(ctx *gin.Context) {
|
2021-11-16 12:13:58 +00:00
|
|
|
route := ctx.Param("route")
|
2020-11-08 17:19:25 +00:00
|
|
|
|
2021-11-16 12:13:58 +00:00
|
|
|
var json RouteAdd
|
|
|
|
if err := ctx.ShouldBindJSON(&json); err != nil {
|
|
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
2020-11-08 17:19:25 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-11-16 12:13:58 +00:00
|
|
|
if err := s.AddMagnet(route, json.Magnet); err != nil {
|
|
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
2020-11-08 17:19:25 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-11-16 12:13:58 +00:00
|
|
|
ctx.JSON(http.StatusOK, nil)
|
2020-11-08 17:19:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-16 12:13:58 +00:00
|
|
|
var apiDelTorrentHandler = func(s *torrent.Service) gin.HandlerFunc {
|
2020-11-08 17:19:25 +00:00
|
|
|
return func(ctx *gin.Context) {
|
2021-11-16 12:13:58 +00:00
|
|
|
route := ctx.Param("route")
|
|
|
|
hash := ctx.Param("torrent_hash")
|
2020-11-09 10:33:19 +00:00
|
|
|
|
2021-11-16 12:13:58 +00:00
|
|
|
if err := s.RemoveFromHash(route, hash); err != nil {
|
|
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
2020-11-09 10:33:19 +00:00
|
|
|
}
|
|
|
|
|
2021-11-16 12:13:58 +00:00
|
|
|
ctx.JSON(http.StatusOK, nil)
|
2020-11-09 10:33:19 +00:00
|
|
|
}
|
|
|
|
}
|
2021-11-20 19:57:25 +00:00
|
|
|
|
|
|
|
var apiLogHandler = func(path string) gin.HandlerFunc {
|
|
|
|
return func(ctx *gin.Context) {
|
|
|
|
f, err := os.Open(path)
|
|
|
|
if err != nil {
|
|
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
fi, err := f.Stat()
|
|
|
|
if err != nil {
|
|
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
max := math.Max(float64(-fi.Size()), -1024*8*8)
|
|
|
|
_, err = f.Seek(int64(max), os.SEEK_END)
|
|
|
|
if err != nil {
|
|
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var b bytes.Buffer
|
|
|
|
ctx.Stream(func(w io.Writer) bool {
|
|
|
|
_, err := b.ReadFrom(f)
|
|
|
|
if err != nil {
|
|
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = b.WriteTo(w)
|
|
|
|
if err != nil {
|
|
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
|
|
|
|
if err := f.Close(); err != nil {
|
|
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|