mirror of
https://gitlab.com/foxixus/neomovies-api.git
synced 2025-10-27 17:38:51 +05:00
ПРОБЛЕМА: - При id_type='kp' код делал fallback на TMDB если фильм не найден - Если передан TMDB ID с id_type='kp', возвращались данные из TMDB - Нарушалась явная логика выбора источника РЕШЕНИЕ: 1. Убран автоматический fallback на TMDB при id_type='kp' 2. Добавлена конвертация ID: - Если id_type='kp' и фильм не найден напрямую - Пробуем конвертировать TMDB ID → KP ID через TmdbIdToKPId - Запрашиваем данные по сконвертированному KP ID 3. Если конвертация не удалась → возвращаем ошибку ЛОГИКА: - id_type='kp' + ID=550 (TMDB): 1. Поиск KP фильма с id=550 → не найдено 2. Конвертация 550 (TMDB) → получаем KP ID (например 326) 3. Поиск KP фильма с id=326 → успех 4. Возврат данных из Kinopoisk ✅ - id_type='kp' + несуществующий ID: 1. Поиск KP фильма → не найдено 2. Конвертация → не удалась 3. Возврат ошибки (НЕ fallback на TMDB) ✅ ИЗМЕНЕНИЯ: - pkg/services/movie.go: добавлена конвертация и удален fallback - pkg/services/tv.go: добавлена конвертация и удален fallback - Добавлен import fmt для форматирования ошибок РЕЗУЛЬТАТ: ✅ Строгое соблюдение id_type параметра ✅ Умная конвертация между TMDB и KP ID ✅ Нет неожиданного fallback на другой источник
130 lines
4.0 KiB
Go
130 lines
4.0 KiB
Go
package services
|
||
|
||
import (
|
||
"fmt"
|
||
"go.mongodb.org/mongo-driver/mongo"
|
||
|
||
"neomovies-api/pkg/models"
|
||
)
|
||
|
||
type MovieService struct {
|
||
tmdb *TMDBService
|
||
kpService *KinopoiskService
|
||
}
|
||
|
||
func NewMovieService(db *mongo.Database, tmdb *TMDBService, kpService *KinopoiskService) *MovieService {
|
||
return &MovieService{
|
||
tmdb: tmdb,
|
||
kpService: kpService,
|
||
}
|
||
}
|
||
|
||
func (s *MovieService) Search(query string, page int, language, region string, year int) (*models.TMDBResponse, error) {
|
||
if ShouldUseKinopoisk(language) && s.kpService != nil {
|
||
kpSearch, err := s.kpService.SearchFilms(query, page)
|
||
if err == nil {
|
||
return MapKPSearchToTMDBResponse(kpSearch), nil
|
||
}
|
||
}
|
||
return s.tmdb.SearchMovies(query, page, language, region, year)
|
||
}
|
||
|
||
func (s *MovieService) GetByID(id int, language string, idType string) (*models.Movie, error) {
|
||
// Если указан id_type, используем его; иначе определяем по языку
|
||
useKP := false
|
||
if idType == "kp" {
|
||
useKP = true
|
||
} else if idType == "tmdb" {
|
||
useKP = false
|
||
} else {
|
||
// Если id_type не указан, используем старую логику по языку
|
||
useKP = ShouldUseKinopoisk(language)
|
||
}
|
||
|
||
if useKP && s.kpService != nil {
|
||
// Сначала пробуем напрямую по KP ID
|
||
kpFilm, err := s.kpService.GetFilmByKinopoiskId(id)
|
||
if err == nil {
|
||
return MapKPFilmToTMDBMovie(kpFilm), nil
|
||
}
|
||
|
||
// Если не найдено и явно указан id_type=kp, возможно это TMDB ID
|
||
// Пробуем конвертировать TMDB -> KP
|
||
if idType == "kp" {
|
||
kpId, convErr := TmdbIdToKPId(s.tmdb, s.kpService, id)
|
||
if convErr == nil {
|
||
kpFilm, err := s.kpService.GetFilmByKinopoiskId(kpId)
|
||
if err == nil {
|
||
return MapKPFilmToTMDBMovie(kpFilm), nil
|
||
}
|
||
}
|
||
// Если конвертация не удалась, возвращаем ошибку вместо fallback
|
||
return nil, fmt.Errorf("film not found in Kinopoisk with id %d", id)
|
||
}
|
||
}
|
||
|
||
// Для TMDB или если KP не указан
|
||
return s.tmdb.GetMovie(id, language)
|
||
}
|
||
|
||
func (s *MovieService) GetPopular(page int, language, region string) (*models.TMDBResponse, error) {
|
||
if ShouldUseKinopoisk(language) && s.kpService != nil {
|
||
kpTop, err := s.kpService.GetTopFilms("TOP_100_POPULAR_FILMS", page)
|
||
if err == nil {
|
||
return MapKPSearchToTMDBResponse(kpTop), nil
|
||
}
|
||
}
|
||
return s.tmdb.GetPopularMovies(page, language, region)
|
||
}
|
||
|
||
func (s *MovieService) GetTopRated(page int, language, region string) (*models.TMDBResponse, error) {
|
||
if ShouldUseKinopoisk(language) && s.kpService != nil {
|
||
kpTop, err := s.kpService.GetTopFilms("TOP_250_BEST_FILMS", page)
|
||
if err == nil {
|
||
return MapKPSearchToTMDBResponse(kpTop), nil
|
||
}
|
||
}
|
||
return s.tmdb.GetTopRatedMovies(page, language, region)
|
||
}
|
||
|
||
func (s *MovieService) GetUpcoming(page int, language, region string) (*models.TMDBResponse, error) {
|
||
return s.tmdb.GetUpcomingMovies(page, language, region)
|
||
}
|
||
|
||
func (s *MovieService) GetNowPlaying(page int, language, region string) (*models.TMDBResponse, error) {
|
||
return s.tmdb.GetNowPlayingMovies(page, language, region)
|
||
}
|
||
|
||
func (s *MovieService) GetRecommendations(id, page int, language string) (*models.TMDBResponse, error) {
|
||
return s.tmdb.GetMovieRecommendations(id, page, language)
|
||
}
|
||
|
||
func (s *MovieService) GetSimilar(id, page int, language string) (*models.TMDBResponse, error) {
|
||
return s.tmdb.GetSimilarMovies(id, page, language)
|
||
}
|
||
|
||
func (s *MovieService) GetExternalIDs(id int) (*models.ExternalIDs, error) {
|
||
if s.kpService != nil {
|
||
kpFilm, err := s.kpService.GetFilmByKinopoiskId(id)
|
||
if err == nil && kpFilm != nil {
|
||
externalIDs := MapKPExternalIDsToTMDB(kpFilm)
|
||
externalIDs.ID = id
|
||
return externalIDs, nil
|
||
}
|
||
}
|
||
|
||
tmdbIDs, err := s.tmdb.GetMovieExternalIDs(id)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
if s.kpService != nil && tmdbIDs.IMDbID != "" {
|
||
kpFilm, err := s.kpService.GetFilmByImdbId(tmdbIDs.IMDbID)
|
||
if err == nil && kpFilm != nil {
|
||
tmdbIDs.KinopoiskID = kpFilm.KinopoiskId
|
||
}
|
||
}
|
||
|
||
return tmdbIDs, nil
|
||
}
|