Add openapi API documentation (#294)

* Initial version

- Add OpenAPI documentation generator
- Update README.md to remove endpoint documentations

* Adds new endpoints

- Fixes build with swag
- Adds new endpoints

* Adds more endpoints documentation

- Also removes swag from Dockerfile and build script

* Finally adds all endpoints documentation

* Initial version

- Add OpenAPI documentation generator
- Update README.md to remove endpoint documentations

* Adds new endpoints

- Fixes build with swag
- Adds new endpoints

* Adds more endpoints documentation

- Also removes swag from Dockerfile and build script

* Finally adds all endpoints documentation

* Update README (#1)

* Update README

I completely redid the `README.md`. Now it's much easier to read and understand.

---------

Co-authored-by: cocool97 <34218602+cocool97@users.noreply.github.com>

* Improves documentation

* Delete server/config.db

* Update README.md

* Update README.md

* fix download in api docs

* add api docs to web

---------

Co-authored-by: Shadeov <144587546+shadeov@users.noreply.github.com>
Co-authored-by: nikk gitanes <tsynik@gmail.com>
This commit is contained in:
cocool97
2023-11-13 07:59:23 +01:00
committed by GitHub
parent aa061fd24c
commit b72c66d433
32 changed files with 5375 additions and 2024 deletions

View File

@@ -15,6 +15,18 @@ type cacheReqJS struct {
Hash string `json:"hash,omitempty"`
}
// cache godoc
//
// @Summary Return cache stats
// @Description Return cache stats.
//
// @Tags API
//
// @Param request body cacheReqJS true "Cache stats request"
//
// @Produce json
// @Success 200 {object} state.CacheState "Cache stats"
// @Router /cache [post]
func cache(c *gin.Context) {
var req cacheReqJS
err := c.ShouldBindJSON(&req)

View File

@@ -40,6 +40,18 @@ func (f *fileReader) Seek(offset int64, whence int) (int64, error) {
return f.pos, nil
}
// download godoc
//
// @Summary Generates test file of given size
// @Description Download the test file of given size (for speed testing purpose).
//
// @Tags API
//
// @Param size path string true "Test file size"
//
// @Produce application/octet-stream
// @Success 200 {file} file
// @Router /download/{size} [get]
func download(c *gin.Context) {
szStr := c.Param("size")
sz, err := strconv.Atoi(szStr)

View File

@@ -11,6 +11,19 @@ import (
"github.com/gin-gonic/gin"
)
// ffp godoc
//
// @Summary Gather informations using ffprobe
// @Description Gather informations using ffprobe.
//
// @Tags API
//
// @Param hash query string true "Torrent hash"
// @Param id query string true "File index in torrent"
//
// @Produce json
// @Success 200 "Data returned from ffprobe"
// @Router /ffp [get]
func ffp(c *gin.Context) {
hash := c.Param("hash")
indexStr := c.Param("id")

View File

@@ -22,6 +22,16 @@ import (
"github.com/pkg/errors"
)
// allPlayList godoc
//
// @Summary Get a M3U playlist with all torrents
// @Description Retrieve all torrents and generates a bundled M3U playlist.
//
// @Tags API
//
// @Produce audio/x-mpegurl
// @Success 200 {file} file
// @Router /playlistall/all.m3u [get]
func allPlayList(c *gin.Context) {
torrs := torr.ListTorrent()
@@ -38,9 +48,19 @@ func allPlayList(c *gin.Context) {
sendM3U(c, "all.m3u", hash, list)
}
// http://127.0.0.1:8090/playlist?hash=...
// http://127.0.0.1:8090/playlist?hash=...&fromlast
// http://127.0.0.1:8090/playlist/fname?hash=...
// playList godoc
//
// @Summary Get HTTP link of torrent in M3U list
// @Description Get HTTP link of torrent in M3U list.
//
// @Tags API
//
// @Param hash query string true "Torrent hash"
// @Param fromlast query bool false "From last play file"
//
// @Produce audio/x-mpegurl
// @Success 200 {file} file
// @Router /playlist [get]
func playList(c *gin.Context) {
hash, _ := c.GetQuery("hash")
_, fromlast := c.GetQuery("fromlast")

View File

@@ -12,6 +12,20 @@ import (
"server/web/api/utils"
)
// play godoc
//
// @Summary Play given torrent referenced by hash
// @Description Play given torrent referenced by hash.
//
// @Tags API
//
// @Param hash query string true "Torrent hash"
// @Param id query string true "File index in torrent"
// @Param not_auth query bool false "Not authenticated"
//
// @Produce application/octet-stream
// @Success 200 "Torrent data"
// @Router /play [get]
func play(c *gin.Context) {
hash := c.Param("hash")
indexStr := c.Param("id")
@@ -69,5 +83,4 @@ func play(c *gin.Context) {
}
tor.Stream(index, c.Request, c.Writer)
return
}

View File

@@ -1,12 +1,7 @@
package api
import (
"net/http"
"time"
"github.com/gin-gonic/gin"
sets "server/settings"
"server/torr"
)
type requestI struct {
@@ -36,7 +31,7 @@ func SetupRoute(route *gin.RouterGroup) {
route.GET("/playlistall/all.m3u", allPlayList)
route.GET("/playlist", playList)
route.GET("/playlist/*fname", playList)
route.GET("/playlist/*fname", playList) // Is this endpoint still needed ? `fname` is never used in handler
route.GET("/download/:size", download)
@@ -44,15 +39,3 @@ func SetupRoute(route *gin.RouterGroup) {
route.GET("/ffp/:hash/:id", ffp)
}
func shutdown(c *gin.Context) {
if sets.ReadOnly {
c.Status(http.StatusForbidden)
return
}
c.Status(200)
go func() {
time.Sleep(1000)
torr.Shutdown()
}()
}

View File

@@ -11,6 +11,18 @@ import (
sets "server/settings"
)
// rutorSearch godoc
//
// @Summary Makes a rutor search
// @Description Makes a rutor search.
//
// @Tags API
//
// @Param query query string true "Rutor query"
//
// @Produce json
// @Success 200 {array} models.TorrentDetails "Rutor torrent search result(s)"
// @Router /search [get]
func rutorSearch(c *gin.Context) {
if !sets.BTsets.EnableRutorSearch {
c.JSON(http.StatusBadRequest, []string{})

View File

@@ -5,9 +5,10 @@ import (
"server/rutor"
"server/dlna"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
"server/dlna"
sets "server/settings"
"server/torr"
@@ -19,6 +20,19 @@ type setsReqJS struct {
Sets *sets.BTSets `json:"sets,omitempty"`
}
// settings godoc
//
// @Summary Get / Set server settings
// @Description Allow to get or set server settings.
//
// @Tags API
//
// @Param request body setsReqJS true "Settings request"
//
// @Accept json
// @Produce json
// @Success 200 {object} sets.BTSets "Depends on what action has been asked"
// @Router /settings [post]
func settings(c *gin.Context) {
var req setsReqJS
err := c.ShouldBindJSON(&req)

View File

@@ -0,0 +1,30 @@
package api
import (
"net/http"
sets "server/settings"
"server/torr"
"time"
"github.com/gin-gonic/gin"
)
// shutdown godoc
// @Summary Shuts down server
// @Description Gracefully shuts down server after 1 second.
//
// @Tags API
//
// @Success 200
// @Router /shutdown [get]
func shutdown(c *gin.Context) {
if sets.ReadOnly {
c.Status(http.StatusForbidden)
return
}
c.Status(200)
go func() {
time.Sleep(1000)
torr.Shutdown()
}()
}

View File

@@ -28,6 +28,28 @@ import (
// only save
// http://127.0.0.1:8090/stream/fname?link=...&save&title=...&poster=...
// stream godoc
//
// @Summary Multi usage endpoint
// @Description Multi usage endpoint.
//
// @Tags API
//
// @Param link query string true "Magnet/hash/link to torrent"
// @Param index query string false "File index in torrent"
// @Param preload query string false "Should preload torrent"
// @Param stat query string false "Get statistics from torrent"
// @Param save query string false "Should save torrent"
// @Param m3u query string false "Get torrent as M3U playlist"
// @Param fromlast query string false "Get m3u from last play"
// @Param play query string false "Start stream torrent"
// @Param title query string true "Set title of torrent"
// @Param poster query string true "File index in torrent"
// @Param not_auth query string true "Set poster link of torrent"
//
// @Produce application/octet-stream
// @Success 200 "Data returned according to query"
// @Router /stream [get]
func stream(c *gin.Context) {
link := c.Query("link")
indexStr := c.Query("index")

View File

@@ -26,6 +26,19 @@ type torrReqJS struct {
SaveToDB bool `json:"save_to_db,omitempty"`
}
// torrents godoc
//
// @Summary Handle torrents informations
// @Description Allow to add, get or set torrents to server. The action depends of what has been asked.
//
// @Tags API
//
// @Param request body torrReqJS true "Torrent request"
//
// @Accept json
// @Produce json
// @Success 200
// @Router /torrents [post]
func torrents(c *gin.Context) {
var req torrReqJS
err := c.ShouldBindJSON(&req)
@@ -59,7 +72,6 @@ func torrents(c *gin.Context) {
{
dropTorrent(req, c)
}
}
}

View File

@@ -3,12 +3,31 @@ package api
import (
"net/http"
"github.com/gin-gonic/gin"
"server/log"
"server/torr"
"server/web/api/utils"
"github.com/gin-gonic/gin"
)
// torrentUpload godoc
//
// @Summary Only one file support
// @Description Only one file support.
//
// @Tags API
//
// @Param file formData file true "Torrent file to insert"
// @Param save formData string false "Save to DB"
// @Param title formData string false "Torrent title"
// @Param poster formData string false "Torrent poster"
// @Param data formData string false "Torrent data"
//
// @Accept multipart/form-data
//
// @Produce json
// @Success 200 {object} state.TorrentStatus "Torrent status"
// @Router /torrent/upload [post]
func torrentUpload(c *gin.Context) {
form, err := c.MultipartForm()
if err != nil {

View File

@@ -3,8 +3,9 @@ package api
import (
"net/http"
"github.com/gin-gonic/gin"
sets "server/settings"
"github.com/gin-gonic/gin"
)
/*
@@ -17,6 +18,19 @@ type viewedReqJS struct {
*sets.Viewed
}
// viewed godoc
//
// @Summary Set / List / Remove viewed torrents
// @Description Allow to set, list or remove viewed torrents from server.
//
// @Tags API
//
// @Param request body viewedReqJS true "Viewed torrent request"
//
// @Accept json
// @Produce json
// @Success 200 {array} sets.Viewed
// @Router /viewed [post]
func viewed(c *gin.Context) {
var req viewedReqJS
err := c.ShouldBindJSON(&req)