Files
neomovies-api/internal/api/handlers.go

506 lines
16 KiB
Go
Raw Normal View History

package api
import (
"net/http"
"github.com/gin-gonic/gin"
"neomovies-api/internal/tmdb"
)
// GetPopularMovies возвращает список популярных фильмов
// @Summary Get popular movies
// @Description Get a list of popular movies
// @Tags movies
// @Accept json
// @Produce json
// @Param page query int false "Page number (default: 1)"
// @Success 200 {object} MoviesResponse
// @Router /movies/popular [get]
func GetPopularMovies(c *gin.Context) {
page := c.DefaultQuery("page", "1")
movies, err := tmdbClient.GetPopular(page)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Добавляем полные URL для изображений
for i := range movies.Results {
if movies.Results[i].PosterPath != "" {
movies.Results[i].PosterPath = tmdbClient.GetImageURL(movies.Results[i].PosterPath, "w500")
}
if movies.Results[i].BackdropPath != "" {
movies.Results[i].BackdropPath = tmdbClient.GetImageURL(movies.Results[i].BackdropPath, "w1280")
}
}
c.JSON(http.StatusOK, movies)
}
// GetMovie возвращает информацию о фильме
// @Summary Get movie details
// @Description Get detailed information about a specific movie
// @Tags movies
// @Accept json
// @Produce json
// @Param id path int true "Movie ID"
// @Success 200 {object} MovieDetails
// @Router /movies/{id} [get]
func GetMovie(c *gin.Context) {
id := c.Param("id")
movie, err := tmdbClient.GetMovie(id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Добавляем полные URL для изображений
if movie.PosterPath != "" {
movie.PosterPath = tmdbClient.GetImageURL(movie.PosterPath, "original")
}
if movie.BackdropPath != "" {
movie.BackdropPath = tmdbClient.GetImageURL(movie.BackdropPath, "original")
}
// Обрабатываем изображения для коллекции
if movie.BelongsToCollection != nil {
if movie.BelongsToCollection.PosterPath != "" {
movie.BelongsToCollection.PosterPath = tmdbClient.GetImageURL(movie.BelongsToCollection.PosterPath, "w500")
}
if movie.BelongsToCollection.BackdropPath != "" {
movie.BelongsToCollection.BackdropPath = tmdbClient.GetImageURL(movie.BelongsToCollection.BackdropPath, "w1280")
}
}
// Обрабатываем логотипы компаний
for i := range movie.ProductionCompanies {
if movie.ProductionCompanies[i].LogoPath != "" {
movie.ProductionCompanies[i].LogoPath = tmdbClient.GetImageURL(movie.ProductionCompanies[i].LogoPath, "w185")
}
}
c.JSON(http.StatusOK, movie)
}
// SearchMovies ищет фильмы
// @Summary Поиск фильмов
// @Description Поиск фильмов по запросу
// @Tags movies
// @Accept json
// @Produce json
// @Param query query string true "Поисковый запрос"
// @Param page query string false "Номер страницы (по умолчанию 1)"
// @Success 200 {object} SearchResponse
// @Router /movies/search [get]
func SearchMovies(c *gin.Context) {
query := c.Query("query")
if query == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "query parameter is required"})
return
}
page := c.DefaultQuery("page", "1")
// Получаем результаты поиска
results, err := tmdbClient.SearchMovies(query, page)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Преобразуем результаты в формат ответа
response := SearchResponse{
Page: results.Page,
TotalPages: results.TotalPages,
TotalResults: results.TotalResults,
Results: make([]MovieResponse, 0),
}
// Преобразуем каждый фильм
for _, movie := range results.Results {
// Форматируем дату
releaseDate := formatDate(movie.ReleaseDate)
// Добавляем фильм в результаты
response.Results = append(response.Results, MovieResponse{
ID: movie.ID,
Title: movie.Title,
Overview: movie.Overview,
ReleaseDate: releaseDate,
VoteAverage: movie.VoteAverage,
PosterPath: tmdbClient.GetImageURL(movie.PosterPath, "w500"),
BackdropPath: tmdbClient.GetImageURL(movie.BackdropPath, "w1280"),
})
}
c.JSON(http.StatusOK, response)
}
// GetTopRatedMovies возвращает список лучших фильмов
// @Summary Get top rated movies
// @Description Get a list of top rated movies
// @Tags movies
// @Accept json
// @Produce json
// @Param page query int false "Page number (default: 1)"
// @Success 200 {object} MoviesResponse
// @Router /movies/top-rated [get]
func GetTopRatedMovies(c *gin.Context) {
page := c.DefaultQuery("page", "1")
movies, err := tmdbClient.GetTopRated(page)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Добавляем полные URL для изображений
for i := range movies.Results {
if movies.Results[i].PosterPath != "" {
movies.Results[i].PosterPath = tmdbClient.GetImageURL(movies.Results[i].PosterPath, "w500")
}
if movies.Results[i].BackdropPath != "" {
movies.Results[i].BackdropPath = tmdbClient.GetImageURL(movies.Results[i].BackdropPath, "w1280")
}
}
c.JSON(http.StatusOK, movies)
}
// GetUpcomingMovies возвращает список предстоящих фильмов
// @Summary Get upcoming movies
// @Description Get a list of upcoming movies
// @Tags movies
// @Accept json
// @Produce json
// @Param page query int false "Page number (default: 1)"
// @Success 200 {object} MoviesResponse
// @Router /movies/upcoming [get]
func GetUpcomingMovies(c *gin.Context) {
page := c.DefaultQuery("page", "1")
movies, err := tmdbClient.GetUpcoming(page)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Добавляем полные URL для изображений
for i := range movies.Results {
if movies.Results[i].PosterPath != "" {
movies.Results[i].PosterPath = tmdbClient.GetImageURL(movies.Results[i].PosterPath, "w500")
}
if movies.Results[i].BackdropPath != "" {
movies.Results[i].BackdropPath = tmdbClient.GetImageURL(movies.Results[i].BackdropPath, "w1280")
}
}
c.JSON(http.StatusOK, movies)
}
// GetTMDBPopularMovies возвращает список популярных фильмов из TMDB
// @Summary Get TMDB popular movies
// @Description Get a list of popular movies directly from TMDB
// @Tags tmdb
// @Accept json
// @Produce json
// @Param page query int false "Page number (default: 1)"
// @Success 200 {object} TMDBMoviesResponse
// @Router /bridge/tmdb/movie/popular [get]
func GetTMDBPopularMovies(c *gin.Context) {
page := c.DefaultQuery("page", "1")
movies, err := tmdbClient.GetPopular(page)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Добавляем полные URL для изображений
for i := range movies.Results {
if movies.Results[i].PosterPath != "" {
movies.Results[i].PosterPath = tmdbClient.GetImageURL(movies.Results[i].PosterPath, "w500")
}
if movies.Results[i].BackdropPath != "" {
movies.Results[i].BackdropPath = tmdbClient.GetImageURL(movies.Results[i].BackdropPath, "w1280")
}
}
c.JSON(http.StatusOK, movies)
}
// GetTMDBMovie возвращает информацию о фильме из TMDB
// @Summary Get TMDB movie details
// @Description Get detailed information about a specific movie directly from TMDB
// @Tags tmdb
// @Accept json
// @Produce json
// @Param id path int true "Movie ID"
// @Success 200 {object} tmdb.Movie
// @Router /bridge/tmdb/movie/{id} [get]
func GetTMDBMovie(c *gin.Context) {
id := c.Param("id")
movie, err := tmdbClient.GetMovie(id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, movie)
}
// GetTMDBTopRatedMovies возвращает список лучших фильмов из TMDB
// @Summary Get TMDB top rated movies
// @Description Get a list of top rated movies directly from TMDB
// @Tags tmdb
// @Accept json
// @Produce json
// @Param page query int false "Page number (default: 1)"
// @Success 200 {object} TMDBMoviesResponse
// @Router /bridge/tmdb/movie/top_rated [get]
func GetTMDBTopRatedMovies(c *gin.Context) {
page := c.DefaultQuery("page", "1")
movies, err := tmdbClient.GetTopRated(page)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Добавляем полные URL для изображений
for i := range movies.Results {
if movies.Results[i].PosterPath != "" {
movies.Results[i].PosterPath = tmdbClient.GetImageURL(movies.Results[i].PosterPath, "w500")
}
if movies.Results[i].BackdropPath != "" {
movies.Results[i].BackdropPath = tmdbClient.GetImageURL(movies.Results[i].BackdropPath, "w1280")
}
}
c.JSON(http.StatusOK, movies)
}
// GetTMDBUpcomingMovies возвращает список предстоящих фильмов из TMDB
// @Summary Get TMDB upcoming movies
// @Description Get a list of upcoming movies directly from TMDB
// @Tags tmdb
// @Accept json
// @Produce json
// @Param page query int false "Page number (default: 1)"
// @Success 200 {object} TMDBMoviesResponse
// @Router /bridge/tmdb/movie/upcoming [get]
func GetTMDBUpcomingMovies(c *gin.Context) {
page := c.DefaultQuery("page", "1")
movies, err := tmdbClient.GetUpcoming(page)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Добавляем полные URL для изображений
for i := range movies.Results {
if movies.Results[i].PosterPath != "" {
movies.Results[i].PosterPath = tmdbClient.GetImageURL(movies.Results[i].PosterPath, "w500")
}
if movies.Results[i].BackdropPath != "" {
movies.Results[i].BackdropPath = tmdbClient.GetImageURL(movies.Results[i].BackdropPath, "w1280")
}
}
c.JSON(http.StatusOK, movies)
}
// SearchTMDBMovies ищет фильмы в TMDB
// @Summary Search TMDB movies
// @Description Search for movies directly in TMDB
// @Tags tmdb
// @Accept json
// @Produce json
// @Param query query string true "Search query"
// @Param page query int false "Page number (default: 1)"
// @Success 200 {object} tmdb.MoviesResponse
// @Router /bridge/tmdb/search/movie [get]
func SearchTMDBMovies(c *gin.Context) {
query := c.Query("query")
if query == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "query parameter is required"})
return
}
page := c.DefaultQuery("page", "1")
movies, err := tmdbClient.SearchMovies(query, page)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, movies)
}
// SearchTMDBTV ищет сериалы в TMDB
// @Summary Search TMDB TV shows
// @Description Search for TV shows directly in TMDB
// @Tags tmdb
// @Accept json
// @Produce json
// @Param query query string true "Search query"
// @Param page query int false "Page number (default: 1)"
// @Success 200 {object} tmdb.TVSearchResults
// @Router /bridge/tmdb/search/tv [get]
func SearchTMDBTV(c *gin.Context) {
query := c.Query("query")
if query == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "query parameter is required"})
return
}
page := c.DefaultQuery("page", "1")
tv, err := tmdbClient.SearchTV(query, page)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, tv)
}
// DiscoverMovies возвращает список фильмов по фильтрам
// @Summary Discover movies
// @Description Get a list of movies based on filters
// @Tags tmdb
// @Accept json
// @Produce json
// @Param page query int false "Page number (default: 1)"
// @Success 200 {object} TMDBMoviesResponse
// @Router /bridge/tmdb/discover/movie [get]
func DiscoverMovies(c *gin.Context) {
page := c.DefaultQuery("page", "1")
movies, err := tmdbClient.DiscoverMovies(page)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, movies)
}
// DiscoverTV возвращает список сериалов по фильтрам
// @Summary Discover TV shows
// @Description Get a list of TV shows based on filters
// @Tags tmdb
// @Accept json
// @Produce json
// @Param page query int false "Page number (default: 1)"
// @Success 200 {object} TMDBMoviesResponse
// @Router /bridge/tmdb/discover/tv [get]
func DiscoverTV(c *gin.Context) {
page := c.DefaultQuery("page", "1")
shows, err := tmdbClient.DiscoverTV(page)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, shows)
}
// GetTMDBMovieExternalIDs возвращает внешние идентификаторы фильма
// @Summary Get TMDB movie external IDs
// @Description Get external IDs (IMDb, Facebook, Instagram, Twitter) for a specific movie
// @Tags tmdb
// @Accept json
// @Produce json
// @Param id path int true "Movie ID"
// @Success 200 {object} tmdb.ExternalIDs
// @Router /bridge/tmdb/movie/{id}/external_ids [get]
func GetTMDBMovieExternalIDs(c *gin.Context) {
id := c.Param("id")
externalIDs, err := tmdbClient.GetMovieExternalIDs(id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, externalIDs)
}
// GetTMDBTVExternalIDs возвращает внешние идентификаторы сериала
// @Summary Get TMDB TV show external IDs
// @Description Get external IDs (IMDb, Facebook, Instagram, Twitter) for a specific TV show
// @Tags tmdb
// @Accept json
// @Produce json
// @Param id path int true "TV Show ID"
// @Success 200 {object} tmdb.ExternalIDs
// @Router /bridge/tmdb/tv/{id}/external_ids [get]
func GetTMDBTVExternalIDs(c *gin.Context) {
id := c.Param("id")
externalIDs, err := tmdbClient.GetTVExternalIDs(id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, externalIDs)
}
// HealthCheck godoc
// @Summary Проверка работоспособности API
// @Description Проверяет, что API работает
// @Tags health
// @Produce json
// @Success 200 {object} map[string]string
// @Router /health [get]
func HealthCheck(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
})
}
// InitTMDBClientWithProxy инициализирует TMDB клиент с прокси
func InitTMDBClientWithProxy(apiKey string, proxyAddr string) error {
tmdbClient = tmdb.NewClient(apiKey)
return tmdbClient.SetSOCKS5Proxy(proxyAddr)
}
// Admin handlers
// GetAdminMovies возвращает список фильмов для админа
func GetAdminMovies(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Admin movies list"})
}
// ToggleMovieVisibility переключает видимость фильма
func ToggleMovieVisibility(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Movie visibility toggled"})
}
// GetUsers возвращает список пользователей
func GetUsers(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Users list"})
}
// CreateUser создает нового пользователя
func CreateUser(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "User created"})
}
// ToggleAdmin переключает права администратора
func ToggleAdmin(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Admin status toggled"})
}
// SendVerification отправляет код верификации
func SendVerification(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Verification code sent"})
}
// VerifyCode проверяет код верификации
func VerifyCode(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Code verified"})
}