diff --git a/apps/vod/api_views.py b/apps/vod/api_views.py index 67813251..eb61f98d 100644 --- a/apps/vod/api_views.py +++ b/apps/vod/api_views.py @@ -120,11 +120,21 @@ class MovieViewSet(viewsets.ReadOnlyModelViewSet): """Get detailed movie information from the original provider, throttled to 24h.""" movie = self.get_object() - # Get the highest priority active relation - relation = M3UMovieRelation.objects.filter( + relation_id = request.query_params.get('relation_id') + qs = M3UMovieRelation.objects.filter( movie=movie, m3u_account__is_active=True - ).select_related('m3u_account').order_by('-m3u_account__priority', 'id').first() + ).select_related('m3u_account') + + if relation_id: + relation = qs.filter(id=relation_id).first() + if not relation: + return Response( + {'error': 'Relation not found or not active'}, + status=status.HTTP_404_NOT_FOUND + ) + else: + relation = qs.order_by('-m3u_account__priority', 'id').first() if not relation: return Response( @@ -326,11 +336,21 @@ class SeriesViewSet(viewsets.ReadOnlyModelViewSet): series = self.get_object() logger.debug(f"Retrieved series: {series.name} (ID: {series.id})") - # Get the highest priority active relation - relation = M3USeriesRelation.objects.filter( + relation_id = request.query_params.get('relation_id') + qs = M3USeriesRelation.objects.filter( series=series, m3u_account__is_active=True - ).select_related('m3u_account').order_by('-m3u_account__priority', 'id').first() + ).select_related('m3u_account') + + if relation_id: + relation = qs.filter(id=relation_id).first() + if not relation: + return Response( + {'error': 'Relation not found or not active'}, + status=status.HTTP_404_NOT_FOUND + ) + else: + relation = qs.order_by('-m3u_account__priority', 'id').first() if not relation: return Response( diff --git a/frontend/src/api.js b/frontend/src/api.js index 2a357a81..def75df5 100644 --- a/frontend/src/api.js +++ b/frontend/src/api.js @@ -3526,10 +3526,11 @@ export default class API { } } - static async getMovieProviderInfo(movieId) { + static async getMovieProviderInfo(movieId, relationId = null) { try { + const params = relationId ? `?relation_id=${relationId}` : ''; const response = await request( - `${host}/api/vod/movies/${movieId}/provider-info/` + `${host}/api/vod/movies/${movieId}/provider-info/${params}` ); return response; } catch (e) { @@ -3568,11 +3569,12 @@ export default class API { } } - static async getSeriesInfo(seriesId) { + static async getSeriesInfo(seriesId, relationId = null) { try { - // Call the provider-info endpoint that includes episodes + const params = new URLSearchParams({ include_episodes: 'true' }); + if (relationId) params.set('relation_id', relationId); const response = await request( - `${host}/api/vod/series/${seriesId}/provider-info/?include_episodes=true` + `${host}/api/vod/series/${seriesId}/provider-info/?${params}` ); return response; } catch (e) { diff --git a/frontend/src/components/SeriesModal.jsx b/frontend/src/components/SeriesModal.jsx index d22e6630..45cb37cd 100644 --- a/frontend/src/components/SeriesModal.jsx +++ b/frontend/src/components/SeriesModal.jsx @@ -470,6 +470,13 @@ const SeriesModal = ({ series, opened, onClose }) => { const onChangeSelectedProvider = (value) => { const provider = providers.find((p) => p.id.toString() === value); setSelectedProvider(provider); + if (provider) { + setLoadingDetails(true); + fetchSeriesInfo(series.id, provider.id) + .then((details) => setDetailedSeries(details)) + .catch(() => {}) + .finally(() => setLoadingDetails(false)); + } }; if (!series) return null; diff --git a/frontend/src/components/VODModal.jsx b/frontend/src/components/VODModal.jsx index c4f5f0cd..679e6544 100644 --- a/frontend/src/components/VODModal.jsx +++ b/frontend/src/components/VODModal.jsx @@ -324,6 +324,11 @@ const VODModal = ({ vod, opened, onClose }) => { const onChangeSelectedProvider = (value) => { const provider = providers.find((p) => p.id.toString() === value); setSelectedProvider(provider); + if (provider) { + fetchMovieDetailsFromProvider(vod.id, provider.id) + .then((details) => setDetailedVOD(details)) + .catch(() => {}); + } } if (!vod) return null; diff --git a/frontend/src/store/useVODStore.jsx b/frontend/src/store/useVODStore.jsx index 966c4a3e..527a4a3a 100644 --- a/frontend/src/store/useVODStore.jsx +++ b/frontend/src/store/useVODStore.jsx @@ -240,10 +240,10 @@ const useVODStore = create((set, get) => ({ } }, - fetchMovieDetailsFromProvider: async (movieId) => { + fetchMovieDetailsFromProvider: async (movieId, relationId = null) => { set({ loading: true, error: null }); try { - const response = await api.getMovieProviderInfo(movieId); + const response = await api.getMovieProviderInfo(movieId, relationId); // Transform the response data to match our expected format const movieDetails = getMovieDetailsWithProvider(response, movieId); @@ -346,10 +346,10 @@ const useVODStore = create((set, get) => ({ return { content: updatedContent }; }), - fetchSeriesInfo: async (seriesId) => { + fetchSeriesInfo: async (seriesId, relationId = null) => { set({ loading: true, error: null }); try { - const response = await api.getSeriesInfo(seriesId); + const response = await api.getSeriesInfo(seriesId, relationId); // Transform the response data to match our expected format const seriesInfo = getSeriesDetails(response, seriesId);