Add and remove torrents from web interface ()

This commit is contained in:
Antonio Navarro Perez 2021-11-16 13:13:58 +01:00 committed by GitHub
parent 02842b1917
commit 2f18213660
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 996 additions and 1170 deletions

View file

@ -1,19 +1,15 @@
package http
import (
"errors"
"io"
"io/ioutil"
"net/http"
"sort"
"github.com/anacrolix/missinggo/v2/filecache"
"github.com/distribyted/distribyted/config"
"github.com/distribyted/distribyted/stats"
"github.com/distribyted/distribyted/torrent"
"github.com/gin-gonic/gin"
)
var apiStatusHandler = func(fc *filecache.Cache, ss *stats.Torrent) gin.HandlerFunc {
var apiStatusHandler = func(fc *filecache.Cache, ss *torrent.Stats) gin.HandlerFunc {
return func(ctx *gin.Context) {
// TODO move to a struct
ctx.JSON(http.StatusOK, gin.H{
@ -25,81 +21,43 @@ var apiStatusHandler = func(fc *filecache.Cache, ss *stats.Torrent) gin.HandlerF
}
}
var apiRoutesHandler = func(ss *stats.Torrent) gin.HandlerFunc {
var apiRoutesHandler = func(ss *torrent.Stats) gin.HandlerFunc {
return func(ctx *gin.Context) {
s := ss.RoutesStats()
sort.Sort(stats.ByName(s))
sort.Sort(torrent.ByName(s))
ctx.JSON(http.StatusOK, s)
}
}
var apiGetConfigFile = func(ch *config.Handler) gin.HandlerFunc {
var apiAddTorrentHandler = func(s *torrent.Service) gin.HandlerFunc {
return func(ctx *gin.Context) {
rc, err := ch.GetRaw()
if err != nil {
ctx.AbortWithError(http.StatusInternalServerError, err)
route := ctx.Param("route")
var json RouteAdd
if err := ctx.ShouldBindJSON(&json); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
ctx.Data(http.StatusOK, "text/x-yaml", rc)
if err := s.AddMagnet(route, json.Magnet); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
ctx.JSON(http.StatusOK, nil)
}
}
var apiSetConfigFile = func(ch *config.Handler) gin.HandlerFunc {
var apiDelTorrentHandler = func(s *torrent.Service) gin.HandlerFunc {
return func(ctx *gin.Context) {
if ctx.Request.Body == nil {
ctx.AbortWithError(http.StatusInternalServerError, errors.New("no config file sent"))
route := ctx.Param("route")
hash := ctx.Param("torrent_hash")
if err := s.RemoveFromHash(route, hash); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c, err := ioutil.ReadAll(ctx.Request.Body)
if err != nil {
ctx.AbortWithError(http.StatusInternalServerError, err)
return
}
if len(c) == 0 {
ctx.AbortWithError(http.StatusInternalServerError, errors.New("no config file sent"))
return
}
if err := ch.Set(c); err != nil {
ctx.AbortWithError(http.StatusInternalServerError, err)
return
}
ctx.JSON(http.StatusOK, gin.H{
"message": "config file saved",
})
}
}
var apiStreamEvents = func(events chan string) gin.HandlerFunc {
return func(ctx *gin.Context) {
ctx.Stream(func(w io.Writer) bool {
if msg, ok := <-events; ok {
ctx.SSEvent("event", msg)
return true
}
return false
})
}
}
var apiReloadServer = func(ch *config.Handler, events chan string) gin.HandlerFunc {
return func(ctx *gin.Context) {
events <- "starting reload configuration process..."
err := ch.Reload(
func(m string) {
events <- m
})
if err != nil {
ctx.AbortWithError(http.StatusInternalServerError, err)
}
ctx.JSON(http.StatusOK, gin.H{
"message": "reload process finished with no errors",
})
ctx.JSON(http.StatusOK, nil)
}
}

View file

@ -6,14 +6,14 @@ import (
"github.com/anacrolix/missinggo/v2/filecache"
"github.com/distribyted/distribyted"
"github.com/distribyted/distribyted/config"
"github.com/distribyted/distribyted/stats"
"github.com/distribyted/distribyted/torrent"
"github.com/gin-contrib/static"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
"github.com/shurcooL/httpfs/html/vfstemplate"
)
func New(fc *filecache.Cache, ss *stats.Torrent, ch *config.Handler, port int) error {
func New(fc *filecache.Cache, ss *torrent.Stats, s *torrent.Service, ch *config.Handler, port int) error {
gin.SetMode(gin.ReleaseMode)
r := gin.New()
r.Use(gin.Recovery())
@ -30,18 +30,14 @@ func New(fc *filecache.Cache, ss *stats.Torrent, ch *config.Handler, port int) e
r.GET("/", indexHandler)
r.GET("/routes", routesHandler(ss))
r.GET("/config", configHandler)
eventChan := make(chan string)
api := r.Group("/api")
{
api.GET("/status", apiStatusHandler(fc, ss))
api.GET("/routes", apiRoutesHandler(ss))
api.GET("/config", apiGetConfigFile(ch))
api.POST("/config", apiSetConfigFile(ch))
api.POST("/reload", apiReloadServer(ch, eventChan))
api.GET("/events", apiStreamEvents(eventChan))
api.POST("/routes/:route/torrent", apiAddTorrentHandler(s))
api.DELETE("/routes/:route/torrent/:torrent_hash", apiDelTorrentHandler(s))
}
log.Info().Str("host", fmt.Sprintf("0.0.0.0:%d", port)).Msg("starting webserver")

9
http/model.go Normal file
View file

@ -0,0 +1,9 @@
package http
type RouteAdd struct {
Magnet string `json:"magnet" binding:"required"`
}
type Error struct {
Error string `json:"error"`
}

View file

@ -3,7 +3,7 @@ package http
import (
"net/http"
"github.com/distribyted/distribyted/stats"
"github.com/distribyted/distribyted/torrent"
"github.com/gin-gonic/gin"
)
@ -11,12 +11,8 @@ var indexHandler = func(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", nil)
}
var routesHandler = func(ss *stats.Torrent) gin.HandlerFunc {
var routesHandler = func(ss *torrent.Stats) gin.HandlerFunc {
return func(c *gin.Context) {
c.HTML(http.StatusOK, "routes.html", ss.RoutesStats())
}
}
var configHandler = func(c *gin.Context) {
c.HTML(http.StatusOK, "config.html", nil)
}