2025-08-07 13:47:42 +00:00
|
|
|
|
package handlers
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"encoding/json"
|
|
|
|
|
|
"fmt"
|
|
|
|
|
|
"net/http"
|
|
|
|
|
|
"os"
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/MarceloPetrucio/go-scalar-api-reference"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2025-08-08 16:47:02 +00:00
|
|
|
|
type DocsHandler struct{}
|
2025-08-07 13:47:42 +00:00
|
|
|
|
|
|
|
|
|
|
func NewDocsHandler() *DocsHandler {
|
|
|
|
|
|
return &DocsHandler{}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (h *DocsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
h.ServeDocs(w, r)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (h *DocsHandler) RedirectToDocs(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
http.Redirect(w, r, "/docs/", http.StatusMovedPermanently)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (h *DocsHandler) GetOpenAPISpec(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
baseURL := os.Getenv("BASE_URL")
|
|
|
|
|
|
if baseURL == "" {
|
|
|
|
|
|
if r.TLS != nil {
|
|
|
|
|
|
baseURL = fmt.Sprintf("https://%s", r.Host)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
baseURL = fmt.Sprintf("http://%s", r.Host)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
spec := getOpenAPISpecWithURL(baseURL)
|
|
|
|
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
|
|
|
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
|
|
|
|
json.NewEncoder(w).Encode(spec)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (h *DocsHandler) ServeDocs(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
baseURL := os.Getenv("BASE_URL")
|
|
|
|
|
|
if baseURL == "" {
|
|
|
|
|
|
if r.TLS != nil {
|
|
|
|
|
|
baseURL = fmt.Sprintf("https://%s", r.Host)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
baseURL = fmt.Sprintf("http://%s", r.Host)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
htmlContent, err := scalar.ApiReferenceHTML(&scalar.Options{
|
|
|
|
|
|
SpecURL: fmt.Sprintf("%s/openapi.json", baseURL),
|
|
|
|
|
|
CustomOptions: scalar.CustomOptions{
|
|
|
|
|
|
PageTitle: "Neo Movies API Documentation",
|
|
|
|
|
|
},
|
|
|
|
|
|
DarkMode: true,
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
fmt.Printf("Error generating documentation: %v", err)
|
|
|
|
|
|
http.Error(w, fmt.Sprintf("Error generating documentation: %v", err), http.StatusInternalServerError)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fmt.Fprintln(w, htmlContent)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type OpenAPISpec struct {
|
|
|
|
|
|
OpenAPI string `json:"openapi"`
|
|
|
|
|
|
Info Info `json:"info"`
|
|
|
|
|
|
Servers []Server `json:"servers"`
|
|
|
|
|
|
Paths map[string]interface{} `json:"paths"`
|
|
|
|
|
|
Components Components `json:"components"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type Info struct {
|
|
|
|
|
|
Title string `json:"title"`
|
|
|
|
|
|
Description string `json:"description"`
|
|
|
|
|
|
Version string `json:"version"`
|
|
|
|
|
|
Contact Contact `json:"contact"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type Contact struct {
|
|
|
|
|
|
Name string `json:"name"`
|
|
|
|
|
|
URL string `json:"url"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type Server struct {
|
|
|
|
|
|
URL string `json:"url"`
|
|
|
|
|
|
Description string `json:"description"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type Components struct {
|
|
|
|
|
|
SecuritySchemes map[string]SecurityScheme `json:"securitySchemes"`
|
|
|
|
|
|
Schemas map[string]interface{} `json:"schemas"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type SecurityScheme struct {
|
|
|
|
|
|
Type string `json:"type"`
|
|
|
|
|
|
Scheme string `json:"scheme,omitempty"`
|
|
|
|
|
|
BearerFormat string `json:"bearerFormat,omitempty"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func getOpenAPISpecWithURL(baseURL string) *OpenAPISpec {
|
|
|
|
|
|
return &OpenAPISpec{
|
|
|
|
|
|
OpenAPI: "3.0.0",
|
|
|
|
|
|
Info: Info{
|
|
|
|
|
|
Title: "Neo Movies API",
|
|
|
|
|
|
Description: "Современный API для поиска фильмов и сериалов с интеграцией TMDB и поддержкой авторизации",
|
|
|
|
|
|
Version: "2.0.0",
|
|
|
|
|
|
Contact: Contact{
|
|
|
|
|
|
Name: "API Support",
|
|
|
|
|
|
URL: "https://github.com/your-username/neomovies-api-go",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
Servers: []Server{
|
|
|
|
|
|
{
|
|
|
|
|
|
URL: baseURL,
|
|
|
|
|
|
Description: "Production server",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
Paths: map[string]interface{}{
|
|
|
|
|
|
"/api/v1/health": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Health Check",
|
|
|
|
|
|
"description": "Проверка работоспособности API",
|
|
|
|
|
|
"tags": []string{"Health"},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "API работает корректно",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"$ref": "#/components/schemas/APIResponse",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/search/multi": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Мультипоиск",
|
|
|
|
|
|
"description": "Поиск фильмов, сериалов и актеров",
|
|
|
|
|
|
"tags": []string{"Search"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "query",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "string"},
|
|
|
|
|
|
"description": "Поисковый запрос",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
|
|
|
|
|
"description": "Номер страницы",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Результаты поиска",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/categories": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Получить категории",
|
|
|
|
|
|
"description": "Получение списка категорий фильмов",
|
|
|
|
|
|
"tags": []string{"Categories"},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Список категорий",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": map[string]interface{}{"$ref": "#/components/schemas/Category"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/categories/{id}/movies": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Фильмы по категории",
|
|
|
|
|
|
"description": "Получение фильмов по категории",
|
|
|
|
|
|
"tags": []string{"Categories"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "id",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "integer"},
|
|
|
|
|
|
"description": "ID категории",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Фильмы категории",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/players/alloha/{imdb_id}": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Плеер Alloha",
|
|
|
|
|
|
"description": "Получение плеера Alloha по IMDb ID",
|
|
|
|
|
|
"tags": []string{"Players"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "imdb_id",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "string"},
|
|
|
|
|
|
"description": "IMDb ID фильма",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Данные плеера",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/players/lumex/{imdb_id}": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Плеер Lumex",
|
|
|
|
|
|
"description": "Получение плеера Lumex по IMDb ID",
|
|
|
|
|
|
"tags": []string{"Players"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "imdb_id",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "string"},
|
|
|
|
|
|
"description": "IMDb ID фильма",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Данные плеера",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
2025-08-11 18:36:02 +00:00
|
|
|
|
"/api/v1/players/vibix/{imdb_id}": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Vibix плеер по IMDb ID",
|
|
|
|
|
|
"description": "Возвращает HTML-страницу с iframe Vibix для указанного IMDb ID",
|
|
|
|
|
|
"tags": []string{"Players"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "imdb_id",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "string"},
|
|
|
|
|
|
"description": "IMDb ID, например tt0133093",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "HTML со встроенным Vibix плеером",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"text/html": map[string]interface{}{},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"404": map[string]interface{}{"description": "Фильм не найден"},
|
|
|
|
|
|
"503": map[string]interface{}{"description": "VIBIX_TOKEN не настроен"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
2025-08-07 13:47:42 +00:00
|
|
|
|
"/api/v1/torrents/search/{imdbId}": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
2025-08-07 18:25:43 +00:00
|
|
|
|
"summary": "Поиск торрентов",
|
2025-08-07 13:47:42 +00:00
|
|
|
|
"description": "Поиск торрентов по IMDB ID",
|
2025-08-07 18:25:43 +00:00
|
|
|
|
"tags": []string{"Torrents"},
|
2025-08-07 13:47:42 +00:00
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
2025-08-07 18:25:43 +00:00
|
|
|
|
"name": "imdbId",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "string"},
|
|
|
|
|
|
"description": "IMDB ID фильма или сериала",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "type",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]interface{}{"type": "string", "enum": []string{"movie", "tv", "serial"}},
|
|
|
|
|
|
"description": "Тип контента: movie (фильм) или tv/serial (сериал)",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "season",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"required": false,
|
|
|
|
|
|
"schema": map[string]interface{}{"type": "integer"},
|
|
|
|
|
|
"description": "Номер сезона (для сериалов)",
|
2025-08-07 13:47:42 +00:00
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Результаты поиска торрентов",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/reactions/{mediaType}/{mediaId}/counts": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Количество реакций",
|
|
|
|
|
|
"description": "Получение количества реакций для медиа",
|
|
|
|
|
|
"tags": []string{"Reactions"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "mediaType",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "string"},
|
|
|
|
|
|
"description": "Тип медиа (movie/tv)",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "mediaId",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "string"},
|
|
|
|
|
|
"description": "ID медиа",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Количество реакций",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"$ref": "#/components/schemas/ReactionCounts",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/images/{size}/{path}": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Изображения",
|
|
|
|
|
|
"description": "Прокси для изображений TMDB",
|
|
|
|
|
|
"tags": []string{"Images"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "size",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "string"},
|
|
|
|
|
|
"description": "Размер изображения",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "path",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "string"},
|
|
|
|
|
|
"description": "Путь к изображению",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Изображение",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"image/*": map[string]interface{}{},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/auth/register": map[string]interface{}{
|
|
|
|
|
|
"post": map[string]interface{}{
|
|
|
|
|
|
"summary": "Регистрация пользователя",
|
|
|
|
|
|
"description": "Создание нового аккаунта пользователя",
|
|
|
|
|
|
"tags": []string{"Authentication"},
|
|
|
|
|
|
"requestBody": map[string]interface{}{
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"$ref": "#/components/schemas/RegisterRequest",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"201": map[string]interface{}{
|
|
|
|
|
|
"description": "Пользователь успешно зарегистрирован",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"$ref": "#/components/schemas/AuthResponse",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"409": map[string]interface{}{
|
|
|
|
|
|
"description": "Пользователь с таким email уже существует",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/auth/verify": map[string]interface{}{
|
|
|
|
|
|
"post": map[string]interface{}{
|
|
|
|
|
|
"tags": []string{"Authentication"},
|
|
|
|
|
|
"summary": "Подтверждение email",
|
|
|
|
|
|
"description": "Подтверждение email пользователя с помощью кода",
|
|
|
|
|
|
"requestBody": map[string]interface{}{
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": []string{"email", "code"},
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"email": map[string]interface{}{
|
|
|
|
|
|
"type": "string",
|
|
|
|
|
|
"format": "email",
|
|
|
|
|
|
"description": "Email пользователя",
|
|
|
|
|
|
"example": "user@example.com",
|
|
|
|
|
|
},
|
|
|
|
|
|
"code": map[string]interface{}{
|
|
|
|
|
|
"type": "string",
|
|
|
|
|
|
"description": "6-значный код верификации",
|
|
|
|
|
|
"example": "123456",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Email успешно подтвержден",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"success": map[string]interface{}{
|
|
|
|
|
|
"type": "boolean",
|
|
|
|
|
|
},
|
|
|
|
|
|
"message": map[string]interface{}{
|
|
|
|
|
|
"type": "string",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"400": map[string]interface{}{
|
|
|
|
|
|
"description": "Неверный или истекший код",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/auth/resend-code": map[string]interface{}{
|
|
|
|
|
|
"post": map[string]interface{}{
|
|
|
|
|
|
"tags": []string{"Authentication"},
|
|
|
|
|
|
"summary": "Повторная отправка кода",
|
|
|
|
|
|
"description": "Повторная отправка кода верификации на email",
|
|
|
|
|
|
"requestBody": map[string]interface{}{
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": []string{"email"},
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"email": map[string]interface{}{
|
|
|
|
|
|
"type": "string",
|
|
|
|
|
|
"format": "email",
|
|
|
|
|
|
"description": "Email пользователя",
|
|
|
|
|
|
"example": "user@example.com",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Код отправлен на email",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"success": map[string]interface{}{
|
|
|
|
|
|
"type": "boolean",
|
|
|
|
|
|
},
|
|
|
|
|
|
"message": map[string]interface{}{
|
|
|
|
|
|
"type": "string",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"400": map[string]interface{}{
|
|
|
|
|
|
"description": "Email уже подтвержден или пользователь не найден",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/auth/login": map[string]interface{}{
|
|
|
|
|
|
"post": map[string]interface{}{
|
|
|
|
|
|
"summary": "Авторизация пользователя",
|
|
|
|
|
|
"description": "Получение JWT токена для доступа к приватным эндпоинтам",
|
|
|
|
|
|
"tags": []string{"Authentication"},
|
|
|
|
|
|
"requestBody": map[string]interface{}{
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"$ref": "#/components/schemas/LoginRequest",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Успешная авторизация",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"$ref": "#/components/schemas/AuthResponse",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"401": map[string]interface{}{
|
|
|
|
|
|
"description": "Неверный email или пароль",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/auth/profile": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Получить профиль пользователя",
|
|
|
|
|
|
"description": "Получение информации о текущем пользователе",
|
|
|
|
|
|
"tags": []string{"Authentication"},
|
|
|
|
|
|
"security": []map[string][]string{
|
|
|
|
|
|
{"bearerAuth": []string{}},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Информация о пользователе",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"$ref": "#/components/schemas/User",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"put": map[string]interface{}{
|
|
|
|
|
|
"summary": "Обновить профиль пользователя",
|
|
|
|
|
|
"description": "Обновление информации о пользователе",
|
|
|
|
|
|
"tags": []string{"Authentication"},
|
|
|
|
|
|
"security": []map[string][]string{
|
|
|
|
|
|
{"bearerAuth": []string{}},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Профиль успешно обновлен",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
2025-08-11 18:36:02 +00:00
|
|
|
|
"delete": map[string]interface{}{
|
2025-08-07 18:25:43 +00:00
|
|
|
|
"summary": "Удалить аккаунт пользователя",
|
|
|
|
|
|
"description": "Полное и безвозвратное удаление аккаунта пользователя и всех связанных с ним данных (избранное, реакции)",
|
|
|
|
|
|
"tags": []string{"Authentication"},
|
|
|
|
|
|
"security": []map[string][]string{
|
|
|
|
|
|
{"bearerAuth": []string{}},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Аккаунт успешно удален",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"success": map[string]interface{}{"type": "boolean"},
|
|
|
|
|
|
"message": map[string]interface{}{"type": "string"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"401": map[string]interface{}{
|
|
|
|
|
|
"description": "Неавторизованный запрос",
|
|
|
|
|
|
},
|
|
|
|
|
|
"500": map[string]interface{}{
|
|
|
|
|
|
"description": "Внутренняя ошибка сервера",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
2025-08-07 13:47:42 +00:00
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/movies/search": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Поиск фильмов",
|
|
|
|
|
|
"description": "Поиск фильмов по названию с поддержкой фильтров",
|
|
|
|
|
|
"tags": []string{"Movies"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "query",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "string"},
|
|
|
|
|
|
"description": "Поисковый запрос",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
|
|
|
|
|
"description": "Номер страницы",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
"description": "Язык ответа",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "year",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer"},
|
|
|
|
|
|
"description": "Год выпуска",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Результаты поиска фильмов",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"$ref": "#/components/schemas/MovieSearchResponse",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/movies/popular": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Популярные фильмы",
|
|
|
|
|
|
"description": "Получение списка популярных фильмов",
|
|
|
|
|
|
"tags": []string{"Movies"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Список популярных фильмов",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/movies/{id}": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Получить фильм по ID",
|
|
|
|
|
|
"description": "Подробная информация о фильме",
|
|
|
|
|
|
"tags": []string{"Movies"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "id",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "integer"},
|
|
|
|
|
|
"description": "ID фильма в TMDB",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Информация о фильме",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"$ref": "#/components/schemas/Movie",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/favorites": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Получить избранные фильмы",
|
|
|
|
|
|
"description": "Список избранных фильмов пользователя",
|
|
|
|
|
|
"tags": []string{"Favorites"},
|
|
|
|
|
|
"security": []map[string][]string{
|
|
|
|
|
|
{"bearerAuth": []string{}},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Список избранных фильмов",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/favorites/{id}": map[string]interface{}{
|
|
|
|
|
|
"post": map[string]interface{}{
|
|
|
|
|
|
"summary": "Добавить в избранное",
|
|
|
|
|
|
"description": "Добавление фильма в избранное",
|
|
|
|
|
|
"tags": []string{"Favorites"},
|
|
|
|
|
|
"security": []map[string][]string{
|
|
|
|
|
|
{"bearerAuth": []string{}},
|
|
|
|
|
|
},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "id",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "string"},
|
|
|
|
|
|
"description": "ID фильма",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Фильм добавлен в избранное",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"delete": map[string]interface{}{
|
|
|
|
|
|
"summary": "Удалить из избранного",
|
|
|
|
|
|
"description": "Удаление фильма из избранного",
|
|
|
|
|
|
"tags": []string{"Favorites"},
|
|
|
|
|
|
"security": []map[string][]string{
|
|
|
|
|
|
{"bearerAuth": []string{}},
|
|
|
|
|
|
},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "id",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "string"},
|
|
|
|
|
|
"description": "ID фильма",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Фильм удален из избранного",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/movies/top-rated": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Топ рейтинг фильмов",
|
|
|
|
|
|
"description": "Получение списка фильмов с высоким рейтингом",
|
|
|
|
|
|
"tags": []string{"Movies"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Список фильмов с высоким рейтингом",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/movies/upcoming": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Скоро в прокате",
|
|
|
|
|
|
"description": "Получение списка фильмов, которые скоро выйдут в прокат",
|
|
|
|
|
|
"tags": []string{"Movies"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Список фильмов, которые скоро выйдут",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/movies/now-playing": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Сейчас в прокате",
|
|
|
|
|
|
"description": "Получение списка фильмов, которые сейчас в прокате",
|
|
|
|
|
|
"tags": []string{"Movies"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Список фильмов в прокате",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/movies/{id}/recommendations": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Рекомендации фильмов",
|
|
|
|
|
|
"description": "Получение рекомендаций фильмов на основе выбранного",
|
|
|
|
|
|
"tags": []string{"Movies"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "id",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "integer"},
|
|
|
|
|
|
"description": "ID фильма в TMDB",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Рекомендуемые фильмы",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/movies/{id}/similar": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Похожие фильмы",
|
|
|
|
|
|
"description": "Получение похожих фильмов",
|
|
|
|
|
|
"tags": []string{"Movies"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "id",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "integer"},
|
|
|
|
|
|
"description": "ID фильма в TMDB",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Похожие фильмы",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/tv/search": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Поиск сериалов",
|
|
|
|
|
|
"description": "Поиск сериалов по названию",
|
|
|
|
|
|
"tags": []string{"TV Series"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "query",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "string"},
|
|
|
|
|
|
"description": "Поисковый запрос",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
2025-08-07 18:25:43 +00:00
|
|
|
|
"description": "Номер страницы",
|
2025-08-07 13:47:42 +00:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
2025-08-07 18:25:43 +00:00
|
|
|
|
"description": "Язык ответа",
|
2025-08-07 13:47:42 +00:00
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Результаты поиска сериалов",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"$ref": "#/components/schemas/TVSearchResponse",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/tv/popular": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Популярные сериалы",
|
|
|
|
|
|
"description": "Получение списка популярных сериалов",
|
|
|
|
|
|
"tags": []string{"TV Series"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Список популярных сериалов",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/tv/top-rated": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Топ рейтинг сериалов",
|
|
|
|
|
|
"description": "Получение списка сериалов с высоким рейтингом",
|
|
|
|
|
|
"tags": []string{"TV Series"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Список сериалов с высоким рейтингом",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/tv/on-the-air": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "В эфире",
|
|
|
|
|
|
"description": "Получение списка сериалов, которые сейчас в эфире",
|
|
|
|
|
|
"tags": []string{"TV Series"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Список сериалов в эфире",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/tv/airing-today": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Сегодня в эфире",
|
|
|
|
|
|
"description": "Получение списка сериалов, которые выходят сегодня",
|
|
|
|
|
|
"tags": []string{"TV Series"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Список сериалов, выходящих сегодня",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/tv/{id}": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Получить сериал по ID",
|
|
|
|
|
|
"description": "Подробная информация о сериале",
|
|
|
|
|
|
"tags": []string{"TV Series"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "id",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "integer"},
|
|
|
|
|
|
"description": "ID сериала в TMDB",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Информация о сериале",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"$ref": "#/components/schemas/TVSeries",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/tv/{id}/recommendations": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Рекомендации сериалов",
|
|
|
|
|
|
"description": "Получение рекомендаций сериалов на основе выбранного",
|
|
|
|
|
|
"tags": []string{"TV Series"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "id",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "integer"},
|
|
|
|
|
|
"description": "ID сериала в TMDB",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Рекомендуемые сериалы",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/tv/{id}/similar": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Похожие сериалы",
|
|
|
|
|
|
"description": "Получение похожих сериалов",
|
|
|
|
|
|
"tags": []string{"TV Series"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "id",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "integer"},
|
|
|
|
|
|
"description": "ID сериала в TMDB",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "page",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "integer", "default": "1"},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "language",
|
|
|
|
|
|
"in": "query",
|
|
|
|
|
|
"schema": map[string]string{"type": "string", "default": "ru-RU"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Похожие сериалы",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/movies/{id}/external-ids": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Внешние идентификаторы фильма",
|
|
|
|
|
|
"description": "Получить внешние ID (IMDb, TVDB, Facebook и др.) для фильма по TMDB ID",
|
|
|
|
|
|
"tags": []string{"Movies"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "id",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "integer"},
|
|
|
|
|
|
"description": "ID фильма в TMDB",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Внешние идентификаторы фильма",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"$ref": "#/components/schemas/ExternalIDs",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/tv/{id}/external-ids": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Внешние идентификаторы сериала",
|
|
|
|
|
|
"description": "Получить внешние ID (IMDb, TVDB, Facebook и др.) для сериала по TMDB ID",
|
|
|
|
|
|
"tags": []string{"TV Series"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "id",
|
|
|
|
|
|
"in": "path",
|
|
|
|
|
|
"required": true,
|
|
|
|
|
|
"schema": map[string]string{"type": "integer"},
|
|
|
|
|
|
"description": "ID сериала в TMDB",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Внешние идентификаторы сериала",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{
|
|
|
|
|
|
"$ref": "#/components/schemas/ExternalIDs",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
2025-08-08 16:47:02 +00:00
|
|
|
|
"/api/v1/auth/google/login": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Google OAuth: начало",
|
|
|
|
|
|
"description": "Редирект на страницу авторизации Google",
|
|
|
|
|
|
"tags": []string{"Authentication"},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"302": map[string]interface{}{"description": "Redirect to Google"},
|
|
|
|
|
|
"400": map[string]interface{}{"description": "OAuth не сконфигурирован"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"/api/v1/auth/google/callback": map[string]interface{}{
|
|
|
|
|
|
"get": map[string]interface{}{
|
|
|
|
|
|
"summary": "Google OAuth: коллбек",
|
|
|
|
|
|
"description": "Обработка кода авторизации и выдача JWT",
|
|
|
|
|
|
"tags": []string{"Authentication"},
|
|
|
|
|
|
"parameters": []map[string]interface{}{
|
|
|
|
|
|
{"name": "state", "in": "query", "required": true, "schema": map[string]string{"type": "string"}},
|
|
|
|
|
|
{"name": "code", "in": "query", "required": true, "schema": map[string]string{"type": "string"}},
|
|
|
|
|
|
},
|
|
|
|
|
|
"responses": map[string]interface{}{
|
|
|
|
|
|
"200": map[string]interface{}{
|
|
|
|
|
|
"description": "Успешная авторизация через Google",
|
|
|
|
|
|
"content": map[string]interface{}{
|
|
|
|
|
|
"application/json": map[string]interface{}{
|
|
|
|
|
|
"schema": map[string]interface{}{"$ref": "#/components/schemas/AuthResponse"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"400": map[string]interface{}{"description": "Неверный state или ошибка обмена кода"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
2025-08-07 13:47:42 +00:00
|
|
|
|
},
|
|
|
|
|
|
Components: Components{
|
|
|
|
|
|
SecuritySchemes: map[string]SecurityScheme{
|
|
|
|
|
|
"bearerAuth": {
|
|
|
|
|
|
Type: "http",
|
|
|
|
|
|
Scheme: "bearer",
|
|
|
|
|
|
BearerFormat: "JWT",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
Schemas: map[string]interface{}{
|
|
|
|
|
|
"APIResponse": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"success": map[string]string{"type": "boolean"},
|
|
|
|
|
|
"data": map[string]string{"type": "object"},
|
|
|
|
|
|
"message": map[string]string{"type": "string"},
|
|
|
|
|
|
"error": map[string]string{"type": "string"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"RegisterRequest": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": []string{"email", "password", "name"},
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"email": map[string]interface{}{
|
|
|
|
|
|
"type": "string",
|
|
|
|
|
|
"format": "email",
|
|
|
|
|
|
"example": "user@example.com",
|
|
|
|
|
|
},
|
|
|
|
|
|
"password": map[string]interface{}{
|
|
|
|
|
|
"type": "string",
|
|
|
|
|
|
"minLength": 6,
|
|
|
|
|
|
"example": "password123",
|
|
|
|
|
|
},
|
|
|
|
|
|
"name": map[string]interface{}{
|
|
|
|
|
|
"type": "string",
|
|
|
|
|
|
"example": "Иван Иванов",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"LoginRequest": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": []string{"email", "password"},
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"email": map[string]interface{}{
|
|
|
|
|
|
"type": "string",
|
|
|
|
|
|
"format": "email",
|
|
|
|
|
|
"example": "user@example.com",
|
|
|
|
|
|
},
|
|
|
|
|
|
"password": map[string]interface{}{
|
|
|
|
|
|
"type": "string",
|
|
|
|
|
|
"example": "password123",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"AuthResponse": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"token": map[string]string{"type": "string"},
|
|
|
|
|
|
"user": map[string]interface{}{"$ref": "#/components/schemas/User"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"User": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"id": map[string]string{"type": "string"},
|
|
|
|
|
|
"email": map[string]string{"type": "string"},
|
|
|
|
|
|
"name": map[string]string{"type": "string"},
|
|
|
|
|
|
"avatar": map[string]string{"type": "string"},
|
|
|
|
|
|
"favorites": map[string]interface{}{
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": map[string]string{"type": "string"},
|
|
|
|
|
|
},
|
|
|
|
|
|
"created_at": map[string]interface{}{
|
|
|
|
|
|
"type": "string",
|
|
|
|
|
|
"format": "date-time",
|
|
|
|
|
|
},
|
|
|
|
|
|
"updated_at": map[string]interface{}{
|
|
|
|
|
|
"type": "string",
|
|
|
|
|
|
"format": "date-time",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"Movie": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"id": map[string]string{"type": "integer"},
|
|
|
|
|
|
"title": map[string]string{"type": "string"},
|
|
|
|
|
|
"original_title": map[string]string{"type": "string"},
|
|
|
|
|
|
"overview": map[string]string{"type": "string"},
|
|
|
|
|
|
"poster_path": map[string]string{"type": "string"},
|
|
|
|
|
|
"backdrop_path": map[string]string{"type": "string"},
|
|
|
|
|
|
"release_date": map[string]string{"type": "string"},
|
|
|
|
|
|
"vote_average": map[string]string{"type": "number"},
|
|
|
|
|
|
"vote_count": map[string]string{"type": "integer"},
|
|
|
|
|
|
"popularity": map[string]string{"type": "number"},
|
|
|
|
|
|
"adult": map[string]string{"type": "boolean"},
|
|
|
|
|
|
"original_language": map[string]string{"type": "string"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"MovieSearchResponse": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"page": map[string]string{"type": "integer"},
|
|
|
|
|
|
"results": map[string]interface{}{
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": map[string]interface{}{"$ref": "#/components/schemas/Movie"},
|
|
|
|
|
|
},
|
|
|
|
|
|
"total_pages": map[string]string{"type": "integer"},
|
|
|
|
|
|
"total_results": map[string]string{"type": "integer"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"TVSeries": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"id": map[string]string{"type": "integer"},
|
|
|
|
|
|
"name": map[string]string{"type": "string"},
|
|
|
|
|
|
"original_name": map[string]string{"type": "string"},
|
|
|
|
|
|
"overview": map[string]string{"type": "string"},
|
|
|
|
|
|
"poster_path": map[string]string{"type": "string"},
|
|
|
|
|
|
"backdrop_path": map[string]string{"type": "string"},
|
|
|
|
|
|
"first_air_date": map[string]string{"type": "string"},
|
|
|
|
|
|
"vote_average": map[string]string{"type": "number"},
|
|
|
|
|
|
"vote_count": map[string]string{"type": "integer"},
|
|
|
|
|
|
"popularity": map[string]string{"type": "number"},
|
|
|
|
|
|
"original_language": map[string]string{"type": "string"},
|
|
|
|
|
|
"number_of_seasons": map[string]string{"type": "integer"},
|
|
|
|
|
|
"number_of_episodes": map[string]string{"type": "integer"},
|
|
|
|
|
|
"status": map[string]string{"type": "string"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"TVSearchResponse": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"page": map[string]string{"type": "integer"},
|
|
|
|
|
|
"results": map[string]interface{}{
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": map[string]interface{}{"$ref": "#/components/schemas/TVSeries"},
|
|
|
|
|
|
},
|
|
|
|
|
|
"total_pages": map[string]string{"type": "integer"},
|
|
|
|
|
|
"total_results": map[string]string{"type": "integer"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"Category": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"id": map[string]string{"type": "integer"},
|
|
|
|
|
|
"name": map[string]string{"type": "string"},
|
|
|
|
|
|
"description": map[string]string{"type": "string"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"Player": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"url": map[string]string{"type": "string"},
|
|
|
|
|
|
"title": map[string]string{"type": "string"},
|
|
|
|
|
|
"quality": map[string]string{"type": "string"},
|
|
|
|
|
|
"type": map[string]string{"type": "string"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"Torrent": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"title": map[string]string{"type": "string"},
|
|
|
|
|
|
"size": map[string]string{"type": "string"},
|
|
|
|
|
|
"seeds": map[string]string{"type": "integer"},
|
|
|
|
|
|
"peers": map[string]string{"type": "integer"},
|
|
|
|
|
|
"magnet": map[string]string{"type": "string"},
|
|
|
|
|
|
"hash": map[string]string{"type": "string"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"Reaction": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"type": map[string]string{"type": "string"},
|
|
|
|
|
|
"count": map[string]string{"type": "integer"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"ReactionCounts": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"like": map[string]string{"type": "integer"},
|
|
|
|
|
|
"dislike": map[string]string{"type": "integer"},
|
|
|
|
|
|
"love": map[string]string{"type": "integer"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
"ExternalIDs": map[string]interface{}{
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": map[string]interface{}{
|
|
|
|
|
|
"id": map[string]string{"type": "integer"},
|
|
|
|
|
|
"imdb_id": map[string]string{"type": "string"},
|
|
|
|
|
|
"tvdb_id": map[string]string{"type": "integer"},
|
|
|
|
|
|
"wikidata_id": map[string]string{"type": "string"},
|
|
|
|
|
|
"facebook_id": map[string]string{"type": "string"},
|
|
|
|
|
|
"instagram_id": map[string]string{"type": "string"},
|
|
|
|
|
|
"twitter_id": map[string]string{"type": "string"},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
2025-08-07 18:25:43 +00:00
|
|
|
|
}
|