Files
neomovies-api/pkg/handlers/categories.go

140 lines
4.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handlers
import (
"encoding/json"
"net/http"
"strconv"
"github.com/gorilla/mux"
"neomovies-api/pkg/models"
"neomovies-api/pkg/services"
)
type CategoriesHandler struct {
tmdbService *services.TMDBService
kpService *services.KinopoiskService
}
func NewCategoriesHandler(tmdbService *services.TMDBService) *CategoriesHandler {
// Для совместимости, kpService может быть добавлен позже через setter при инициализации в main.go/api/index.go
return &CategoriesHandler{tmdbService: tmdbService}
}
func (h *CategoriesHandler) WithKinopoisk(kp *services.KinopoiskService) *CategoriesHandler {
h.kpService = kp
return h
}
type Category struct {
ID int `json:"id"`
Name string `json:"name"`
Slug string `json:"slug"`
}
func (h *CategoriesHandler) GetCategories(w http.ResponseWriter, r *http.Request) {
// Получаем все жанры
genresResponse, err := h.tmdbService.GetAllGenres()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Преобразуем жанры в категории (пока TMDB). Для KP — можно замаппить фиксированный список
var categories []Category
for _, genre := range genresResponse.Genres {
slug := generateSlug(genre.Name)
categories = append(categories, Category{
ID: genre.ID,
Name: genre.Name,
Slug: slug,
})
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(models.APIResponse{
Success: true,
Data: categories,
})
}
func (h *CategoriesHandler) GetMediaByCategory(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
categoryID, err := strconv.Atoi(vars["id"])
if err != nil {
http.Error(w, "Invalid category ID", http.StatusBadRequest)
return
}
page := getIntQuery(r, "page", 1)
language := r.URL.Query().Get("language")
if language == "" {
language = "ru-RU"
}
mediaType := r.URL.Query().Get("type")
if mediaType == "" {
mediaType = "movie" // По умолчанию фильмы для обратной совместимости
}
if mediaType != "movie" && mediaType != "tv" {
http.Error(w, "Media type must be 'movie' or 'tv'", http.StatusBadRequest)
return
}
source := r.URL.Query().Get("source") // "kp" | "tmdb"
var data interface{}
var err2 error
if source == "kp" && h.kpService != nil {
// KP не имеет прямого discover по genre id TMDB — здесь можно реализовать маппинг slug->поисковый запрос
// Для простоты: используем keyword поиск по имени категории (slug как ключевое слово)
// Получим человекочитаемое имя жанра из TMDB как приближение
if mediaType == "movie" {
// Поиском KP (keyword) эмулируем категорию
data, err2 = h.kpService.SearchFilms(r.URL.Query().Get("name"), page)
} else {
// Для сериалов у KP: используем тот же поиск (KP выдаёт и сериалы в некоторых случаях)
data, err2 = h.kpService.SearchFilms(r.URL.Query().Get("name"), page)
}
} else {
if mediaType == "movie" {
data, err2 = h.tmdbService.DiscoverMoviesByGenre(categoryID, page, language)
} else {
data, err2 = h.tmdbService.DiscoverTVByGenre(categoryID, page, language)
}
}
if err2 != nil {
http.Error(w, err2.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(models.APIResponse{
Success: true,
Data: data,
Message: "Media retrieved successfully",
})
}
// Старый метод для обратной совместимости
func (h *CategoriesHandler) GetMoviesByCategory(w http.ResponseWriter, r *http.Request) {
// Просто перенаправляем на новый метод
h.GetMediaByCategory(w, r)
}
func generateSlug(name string) string {
// Простая функция для создания slug из названия
// В реальном проекте стоит использовать более сложную логику
result := ""
for _, char := range name {
if (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9') {
result += string(char)
} else if char == ' ' {
result += "-"
}
}
return result
}