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

@@ -14,6 +14,7 @@ import (
"github.com/pkg/browser"
"server"
"server/docs"
"server/log"
"server/settings"
"server/torr"
@@ -69,6 +70,8 @@ func main() {
log.TLogln("Use HTTP Auth file", settings.Path+"/accs.db")
}
docs.SwaggerInfo.Version = version.Version
dnsResolve()
Preconfig(params.DontKill)

1092
server/docs/docs.go Normal file

File diff suppressed because it is too large Load Diff

1067
server/docs/swagger.json Normal file

File diff suppressed because it is too large Load Diff

711
server/docs/swagger.yaml Normal file
View File

@@ -0,0 +1,711 @@
basePath: /
definitions:
api.cacheReqJS:
properties:
action:
type: string
hash:
type: string
type: object
api.setsReqJS:
properties:
action:
type: string
sets:
$ref: '#/definitions/settings.BTSets'
type: object
api.torrReqJS:
properties:
action:
type: string
data:
type: string
hash:
type: string
link:
type: string
poster:
type: string
save_to_db:
type: boolean
title:
type: string
type: object
api.viewedReqJS:
properties:
action:
type: string
file_index:
type: integer
hash:
type: string
type: object
models.TorrentDetails:
properties:
audioQuality:
type: integer
categories:
type: string
createDate:
type: string
hash:
type: string
imdbid:
type: string
link:
type: string
magnet:
type: string
name:
type: string
names:
items:
type: string
type: array
peer:
type: integer
seed:
type: integer
size:
type: string
title:
type: string
tracker:
type: string
videoQuality:
type: integer
year:
type: integer
type: object
settings.BTSets:
properties:
cacheSize:
description: Cache
type: integer
connectionsLimit:
type: integer
disableDHT:
type: boolean
disablePEX:
type: boolean
disableTCP:
type: boolean
disableUPNP:
type: boolean
disableUTP:
type: boolean
disableUpload:
type: boolean
downloadRateLimit:
description: in kb, 0 - inf
type: integer
enableDLNA:
description: DLNA
type: boolean
enableDebug:
description: debug logs
type: boolean
enableIPv6:
description: BT Config
type: boolean
enableRutorSearch:
description: Rutor
type: boolean
forceEncrypt:
description: Torrent
type: boolean
friendlyName:
type: string
peersListenPort:
type: integer
preloadCache:
description: in percent
type: integer
readerReadAHead:
description: in percent, 5%-100%, [...S__X__E...] [S-E] not clean
type: integer
removeCacheOnDrop:
type: boolean
retrackersMode:
description: 0 - don`t add, 1 - add retrackers (def), 2 - remove retrackers
3 - replace retrackers
type: integer
sslCert:
type: string
sslKey:
type: string
sslPort:
description: HTTPS
type: integer
torrentDisconnectTimeout:
description: in seconds
type: integer
torrentsSavePath:
type: string
uploadRateLimit:
description: in kb, 0 - inf
type: integer
useDisk:
description: Disk
type: boolean
type: object
settings.Viewed:
properties:
file_index:
type: integer
hash:
type: string
type: object
state.CacheState:
properties:
capacity:
type: integer
filled:
type: integer
hash:
type: string
pieces:
additionalProperties:
$ref: '#/definitions/state.ItemState'
type: object
piecesCount:
type: integer
piecesLength:
type: integer
readers:
items:
$ref: '#/definitions/state.ReaderState'
type: array
torrent:
$ref: '#/definitions/state.TorrentStatus'
type: object
state.ItemState:
properties:
completed:
type: boolean
id:
type: integer
length:
type: integer
priority:
type: integer
size:
type: integer
type: object
state.ReaderState:
properties:
end:
type: integer
reader:
type: integer
start:
type: integer
type: object
state.TorrentFileStat:
properties:
id:
type: integer
length:
type: integer
path:
type: string
type: object
state.TorrentStat:
enum:
- 0
- 1
- 2
- 3
- 4
- 5
type: integer
x-enum-varnames:
- TorrentAdded
- TorrentGettingInfo
- TorrentPreload
- TorrentWorking
- TorrentClosed
- TorrentInDB
state.TorrentStatus:
properties:
active_peers:
type: integer
bit_rate:
type: string
bytes_read:
type: integer
bytes_read_data:
type: integer
bytes_read_useful_data:
type: integer
bytes_written:
type: integer
bytes_written_data:
type: integer
chunks_read:
type: integer
chunks_read_useful:
type: integer
chunks_read_wasted:
type: integer
chunks_written:
type: integer
connected_seeders:
type: integer
data:
type: string
download_speed:
type: number
duration_seconds:
type: number
file_stats:
items:
$ref: '#/definitions/state.TorrentFileStat'
type: array
half_open_peers:
type: integer
hash:
type: string
loaded_size:
type: integer
name:
type: string
pending_peers:
type: integer
pieces_dirtied_bad:
type: integer
pieces_dirtied_good:
type: integer
poster:
type: string
preload_size:
type: integer
preloaded_bytes:
type: integer
stat:
$ref: '#/definitions/state.TorrentStat'
stat_string:
type: string
timestamp:
type: integer
title:
type: string
torrent_size:
type: integer
total_peers:
type: integer
upload_speed:
type: number
type: object
externalDocs:
description: OpenAPI
url: https://swagger.io/resources/open-api/
info:
contact: {}
description: Torrent streaming server.
license:
name: GPL 3.0
title: Swagger Torrserver API
version: '{version.Version}'
paths:
/cache:
post:
description: Return cache stats.
parameters:
- description: Cache stats request
in: body
name: request
required: true
schema:
$ref: '#/definitions/api.cacheReqJS'
produces:
- application/json
responses:
"200":
description: Cache stats
schema:
$ref: '#/definitions/state.CacheState'
summary: Return cache stats
tags:
- API
/download/{size}:
get:
description: Download the test file of given size (for speed testing purpose).
parameters:
- description: Test file size
in: path
name: size
required: true
type: string
produces:
- application/octet-stream
responses:
"200":
description: OK
schema:
type: file
summary: Generates test file of given size
tags:
- API
/echo:
get:
description: Tests whether server is alive or not
produces:
- text/plain
responses:
"200":
description: Server version
schema:
type: string
summary: Tests server status
tags:
- API
/ffp:
get:
description: Gather informations using ffprobe.
parameters:
- description: Torrent hash
in: query
name: hash
required: true
type: string
- description: File index in torrent
in: query
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Data returned from ffprobe
summary: Gather informations using ffprobe
tags:
- API
/magnets:
get:
description: Get HTML of magnet links.
produces:
- text/html
responses:
"200":
description: Magnet links
summary: Get HTML of magnet links
tags:
- Pages
/msx:
get:
description: Multi usage endpoint.
parameters:
- description: Magnet/hash/link to torrent
in: query
name: link
required: true
type: string
produces:
- application/json
responses:
"200":
description: Data returned according to query
summary: Multi usage endpoint
tags:
- MSX
/msx/imdb:
get:
description: Get MSX IMDB informations.
produces:
- application/json
responses:
"200":
description: JSON MSX IMDB informations
summary: Get MSX IMDB informations
tags:
- MSX
/msx/imdb/:id:
get:
description: Get MSX IMDB informations.
parameters:
- description: IMDB ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: JSON MSX IMDB informations
summary: Get MSX IMDB informations
tags:
- MSX
/play:
get:
description: Play given torrent referenced by hash.
parameters:
- description: Torrent hash
in: query
name: hash
required: true
type: string
- description: File index in torrent
in: query
name: id
required: true
type: string
- description: Not authenticated
in: query
name: not_auth
type: boolean
produces:
- application/octet-stream
responses:
"200":
description: Torrent data
summary: Play given torrent referenced by hash
tags:
- API
/playlist:
get:
description: Get HTTP link of torrent in M3U list.
parameters:
- description: Torrent hash
in: query
name: hash
required: true
type: string
- description: From last play file
in: query
name: fromlast
type: boolean
produces:
- audio/x-mpegurl
responses:
"200":
description: OK
schema:
type: file
summary: Get HTTP link of torrent in M3U list
tags:
- API
/playlistall/all.m3u:
get:
description: Retrieve all torrents and generates a bundled M3U playlist.
produces:
- audio/x-mpegurl
responses:
"200":
description: OK
schema:
type: file
summary: Get a M3U playlist with all torrents
tags:
- API
/search:
get:
description: Makes a rutor search.
parameters:
- description: Rutor query
in: query
name: query
required: true
type: string
produces:
- application/json
responses:
"200":
description: Rutor torrent search result(s)
schema:
items:
$ref: '#/definitions/models.TorrentDetails'
type: array
summary: Makes a rutor search
tags:
- API
/settings:
post:
consumes:
- application/json
description: Allow to get or set server settings.
parameters:
- description: Settings request
in: body
name: request
required: true
schema:
$ref: '#/definitions/api.setsReqJS'
produces:
- application/json
responses:
"200":
description: Depends on what action has been asked
schema:
$ref: '#/definitions/settings.BTSets'
summary: Get / Set server settings
tags:
- API
/shutdown:
get:
description: Gracefully shuts down server after 1 second.
responses:
"200":
description: OK
summary: Shuts down server
tags:
- API
/stat:
get:
description: Stat server.
produces:
- text/plain
responses:
"200":
description: Stats
summary: Stat server
tags:
- Pages
/stream:
get:
description: Multi usage endpoint.
parameters:
- description: Magnet/hash/link to torrent
in: query
name: link
required: true
type: string
- description: File index in torrent
in: query
name: index
type: string
- description: Should preload torrent
in: query
name: preload
type: string
- description: Get statistics from torrent
in: query
name: stat
type: string
- description: Should save torrent
in: query
name: save
type: string
- description: Get torrent as M3U playlist
in: query
name: m3u
type: string
- description: Get m3u from last play
in: query
name: fromlast
type: string
- description: Start stream torrent
in: query
name: play
type: string
- description: Set title of torrent
in: query
name: title
required: true
type: string
- description: File index in torrent
in: query
name: poster
required: true
type: string
- description: Set poster link of torrent
in: query
name: not_auth
required: true
type: string
produces:
- application/octet-stream
responses:
"200":
description: Data returned according to query
summary: Multi usage endpoint
tags:
- API
/torrent/upload:
post:
consumes:
- multipart/form-data
description: Only one file support.
parameters:
- description: Torrent file to insert
in: formData
name: file
required: true
type: file
- description: Save to DB
in: formData
name: save
type: string
- description: Torrent title
in: formData
name: title
type: string
- description: Torrent poster
in: formData
name: poster
type: string
- description: Torrent data
in: formData
name: data
type: string
produces:
- application/json
responses:
"200":
description: Torrent status
schema:
$ref: '#/definitions/state.TorrentStatus'
summary: Only one file support
tags:
- API
/torrents:
post:
consumes:
- application/json
description: Allow to add, get or set torrents to server. The action depends
of what has been asked.
parameters:
- description: Torrent request
in: body
name: request
required: true
schema:
$ref: '#/definitions/api.torrReqJS'
produces:
- application/json
responses:
"200":
description: OK
summary: Handle torrents informations
tags:
- API
/viewed:
post:
consumes:
- application/json
description: Allow to set, list or remove viewed torrents from server.
parameters:
- description: Viewed torrent request
in: body
name: request
required: true
schema:
$ref: '#/definitions/api.viewedReqJS'
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/settings.Viewed'
type: array
summary: Set / List / Remove viewed torrents
tags:
- API
securityDefinitions:
BasicAuth:
type: basic
swagger: "2.0"

View File

@@ -18,6 +18,9 @@ require (
github.com/kljensen/snowball v0.8.0
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
github.com/pkg/errors v0.9.1
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.0
github.com/swaggo/swag v1.16.2
go.etcd.io/bbolt v1.3.8
golang.org/x/image v0.13.0
golang.org/x/time v0.3.0
@@ -25,6 +28,7 @@ require (
)
require (
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/RoaringBitmap/roaring v1.6.0 // indirect
github.com/alecthomas/atomic v0.1.0-alpha2 // indirect
github.com/alexflint/go-scalar v1.2.0 // indirect
@@ -51,15 +55,21 @@ require (
github.com/frankban/quicktest v1.14.6 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/spec v0.20.9 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.15.5 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
@@ -76,6 +86,7 @@ require (
golang.org/x/sync v0.4.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.14.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

View File

@@ -4,6 +4,8 @@ crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797/go.mod h1:sXBiorCo8c46JlQV3oX
crawshaw.io/sqlite v0.3.2/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4=
filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w=
github.com/RoaringBitmap/roaring v0.4.17/go.mod h1:D3qVegWTmfCaX4Bl5CrBE9hfrSrrXIr8KVNvRsDi1NI=
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
@@ -128,6 +130,7 @@ github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uq
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g=
github.com/gin-contrib/cors v1.4.0/go.mod h1:bs9pNM0x/UsmHPBWT2xZz9ROh8xYjYkiURUfmBoMlcs=
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
github.com/gin-contrib/location v0.0.2 h1:QZKh1+K/LLR4KG/61eIO3b7MLuKi8tytQhV6texLgP4=
github.com/gin-contrib/location v0.0.2/go.mod h1:NGoidiRlf0BlA/VKSVp+g3cuSMeTmip/63PhEjRhUAc=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
@@ -146,6 +149,21 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA=
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8=
github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
@@ -208,6 +226,8 @@ github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@@ -237,6 +257,11 @@ github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgx
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@@ -254,6 +279,7 @@ github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@@ -319,6 +345,12 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M=
github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=
github.com/swaggo/swag v1.16.2 h1:28Pp+8DkQoV+HLzLx8RGJZXNGKbFqnuvSbAAtoxiY04=
github.com/swaggo/swag v1.16.2/go.mod h1:6YzXnDcpr0767iOejs318CwYkCQqyGer6BizOg03f+E=
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
@@ -335,6 +367,7 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ
github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA=
go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
@@ -362,6 +395,8 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -376,6 +411,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220524220425-1d687d428aca/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -387,6 +424,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -411,17 +449,20 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
@@ -434,6 +475,9 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -460,6 +504,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
@@ -472,8 +517,10 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

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)

View File

@@ -31,68 +31,108 @@ func asset(c *gin.Context, t string, d []byte) {
}
func SetupRoute(r *gin.RouterGroup) {
r.GET("/msx/:pth", func(c *gin.Context) {
js := []string{"http://msx.benzac.de/js/tvx-plugin.min.js"}
switch p := c.Param("pth"); p {
case "start.json":
c.JSON(200, map[string]string{
"name": "TorrServer",
"version": version.Version,
"parameter": "menu:request:interaction:init@{PREFIX}{SERVER}/msx/ts",
})
case "russian.json":
asset(c, "application/json", rus)
case "torrents.js":
asset(c, "text/javascript", trs)
case "torrent.js":
asset(c, "text/javascript", trn)
case "ts.js":
asset(c, "text/javascript", its)
case "torrents":
js = append(js, p+".js")
p = "torrent"
fallthrough
case "torrent":
if c.Query("platform") == "tizen" {
js = append(js, "http://msx.benzac.de/interaction/js/tizen-player.js")
}
fallthrough
case "ts":
b := []byte("<!DOCTYPE html>\n<html>\n<head>\n<title>TorrServer Plugin</title>\n<meta charset='UTF-8'>\n")
for _, j := range append(js, p+".js") {
b = append(b, "<script type='text/javascript' src='"+j+"'></script>\n"...)
}
c.Data(200, "text/html; charset=UTF-8", append(b, "</head>\n<body></body>\n</html>"...))
default:
c.AbortWithStatus(404)
r.GET("/msx/:pth", msxPTH)
r.GET("/msx/imdb", msxIMDB)
r.GET("/msx/imdb/:id", msxIMDBID)
}
// msxPTH godoc
//
// @Summary Multi usage endpoint
// @Description Multi usage endpoint.
//
// @Tags MSX
//
// @Param link query string true "Magnet/hash/link to torrent"
//
// @Produce json
// @Success 200 "Data returned according to query"
// @Router /msx [get]
func msxPTH(c *gin.Context) {
js := []string{"http://msx.benzac.de/js/tvx-plugin.min.js"}
switch p := c.Param("pth"); p {
case "start.json":
c.JSON(200, map[string]string{
"name": "TorrServer",
"version": version.Version,
"parameter": "menu:request:interaction:init@{PREFIX}{SERVER}/msx/ts",
})
case "russian.json":
asset(c, "application/json", rus)
case "torrents.js":
asset(c, "text/javascript", trs)
case "torrent.js":
asset(c, "text/javascript", trn)
case "ts.js":
asset(c, "text/javascript", its)
case "torrents":
js = append(js, p+".js")
p = "torrent"
fallthrough
case "torrent":
if c.Query("platform") == "tizen" {
js = append(js, "http://msx.benzac.de/interaction/js/tizen-player.js")
}
})
r.GET("/msx/imdb", func(c *gin.Context) {
idb.Lock()
defer idb.Unlock()
l := len(ids)
ids = make(map[string]string)
c.JSON(200, l)
})
r.GET("/msx/imdb/:id", func(c *gin.Context) {
idb.Lock()
defer idb.Unlock()
p := c.Param("id")
i, o := ids[p]
if !o {
if r, e := http.Get("https://v2.sg.media-imdb.com/suggestion/h/" + p + ".json"); e == nil {
defer r.Body.Close()
if r.StatusCode == 200 {
var j struct {
D []struct{ I struct{ ImageUrl string } }
}
if e = json.NewDecoder(r.Body).Decode(&j); e == nil && len(j.D) > 0 {
i = j.D[0].I.ImageUrl
}
fallthrough
case "ts":
b := []byte("<!DOCTYPE html>\n<html>\n<head>\n<title>TorrServer Plugin</title>\n<meta charset='UTF-8'>\n")
for _, j := range append(js, p+".js") {
b = append(b, "<script type='text/javascript' src='"+j+"'></script>\n"...)
}
c.Data(200, "text/html; charset=UTF-8", append(b, "</head>\n<body></body>\n</html>"...))
default:
c.AbortWithStatus(404)
}
}
// msxIMDB godoc
//
// @Summary Get MSX IMDB informations
// @Description Get MSX IMDB informations.
//
// @Tags MSX
//
// @Produce json
// @Success 200 "JSON MSX IMDB informations"
// @Router /msx/imdb [get]
func msxIMDB(c *gin.Context) {
idb.Lock()
defer idb.Unlock()
l := len(ids)
ids = make(map[string]string)
c.JSON(200, l)
}
// msxIMDB godoc
//
// @Summary Get MSX IMDB informations
// @Description Get MSX IMDB informations.
//
// @Tags MSX
//
// @Param id path string true "IMDB ID"
//
// @Produce json
// @Success 200 "JSON MSX IMDB informations"
// @Router /msx/imdb/:id [get]
func msxIMDBID(c *gin.Context) {
idb.Lock()
defer idb.Unlock()
p := c.Param("id")
i, o := ids[p]
if !o {
if r, e := http.Get("https://v2.sg.media-imdb.com/suggestion/h/" + p + ".json"); e == nil {
defer r.Body.Close()
if r.StatusCode == 200 {
var j struct {
D []struct{ I struct{ ImageUrl string } }
}
if e = json.NewDecoder(r.Body).Decode(&j); e == nil && len(j.D) > 0 {
i = j.D[0].I.ImageUrl
}
}
ids[p] = i
}
c.JSON(200, i)
})
ids[p] = i
}
c.JSON(200, i)
}

View File

@@ -15,11 +15,31 @@ func SetupRoute(route *gin.RouterGroup) {
route.GET("/magnets", getTorrents)
}
// stat godoc
//
// @Summary Stat server
// @Description Stat server.
//
// @Tags Pages
//
// @Produce text/plain
// @Success 200 "Stats"
// @Router /stat [get]
func statPage(c *gin.Context) {
torr.WriteStatus(c.Writer)
c.Status(200)
}
// getTorrents godoc
//
// @Summary Get HTML of magnet links
// @Description Get HTML of magnet links.
//
// @Tags Pages
//
// @Produce text/html
// @Success 200 "Magnet links"
// @Router /magnets [get]
func getTorrents(c *gin.Context) {
list := settings.ListTorrent()
http := "<div>"

View File

@@ -23,6 +23,9 @@ import (
"server/web/blocker"
"server/web/pages"
"server/web/sslcerts"
swaggerFiles "github.com/swaggo/files" // swagger embed files
ginSwagger "github.com/swaggo/gin-swagger" // gin-swagger middleware
)
var (
@@ -30,6 +33,18 @@ var (
waitChan = make(chan error)
)
// @title Swagger Torrserver API
// @version {version.Version}
// @description Torrent streaming server.
// @license.name GPL 3.0
// @BasePath /
// @securityDefinitions.basic BasicAuth
// @externalDocs.description OpenAPI
// @externalDocs.url https://swagger.io/resources/open-api/
func Start() {
log.TLogln("Start TorrServer " + version.Version + " torrent " + version.GetTorrentVersion())
ips := getLocalIps()
@@ -72,6 +87,8 @@ func Start() {
if settings.BTsets.EnableDLNA {
dlna.Start()
}
route.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
//check if https enabled
if settings.Ssl {
@@ -113,6 +130,16 @@ func Stop() {
waitChan <- nil
}
// echo godoc
//
// @Summary Tests server status
// @Description Tests whether server is alive or not
//
// @Tags API
//
// @Produce plain
// @Success 200 {string} string "Server version"
// @Router /echo [get]
func echo(c *gin.Context) {
c.String(200, "%v", version.Version)
}