Add XC endpoints for VOD.

This commit is contained in:
SergeantPanda 2025-08-08 09:03:25 -05:00
parent 00361c15b9
commit d054e2cac5
3 changed files with 111 additions and 1 deletions

View file

@ -1,5 +1,5 @@
from django.urls import path, re_path, include
from .views import m3u_endpoint, epg_endpoint, xc_get
from .views import m3u_endpoint, epg_endpoint, xc_get, xc_movie_stream, xc_series_stream
from core.views import stream_view
app_name = "output"

View file

@ -1373,3 +1373,101 @@ def xc_get_vod_info(request, user, vod_id):
}
return info
def xc_movie_stream(request, username, password, stream_id, extension):
"""Handle XtreamCodes movie streaming requests"""
from apps.vod.models import M3UMovieRelation
user = get_object_or_404(User, username=username)
custom_properties = (
json.loads(user.custom_properties) if user.custom_properties else {}
)
if "xc_password" not in custom_properties:
return JsonResponse({"error": "Invalid credentials"}, status=401)
if custom_properties["xc_password"] != password:
return JsonResponse({"error": "Invalid credentials"}, status=401)
# Get movie relation based on user access level
filters = {"id": stream_id, "m3u_account__is_active": True}
if user.user_level < 10:
# For regular users, filter by accessible M3U accounts
if user.channel_profiles.count() > 0:
channel_profiles = user.channel_profiles.all()
from apps.m3u.models import M3UAccount
m3u_accounts = M3UAccount.objects.filter(
is_active=True,
profiles__in=channel_profiles
).distinct()
filters["m3u_account__in"] = m3u_accounts
else:
return JsonResponse({"error": "No accessible content"}, status=403)
try:
movie_relation = M3UMovieRelation.objects.select_related('movie').get(**filters)
except M3UMovieRelation.DoesNotExist:
return JsonResponse({"error": "Movie not found"}, status=404)
# Redirect to the VOD proxy endpoint
from django.http import HttpResponseRedirect
from django.urls import reverse
vod_url = reverse('proxy:vod_proxy:vod_stream', kwargs={
'content_type': 'movie',
'content_id': movie_relation.movie.uuid
})
return HttpResponseRedirect(vod_url)
def xc_series_stream(request, username, password, stream_id, extension):
"""Handle XtreamCodes series/episode streaming requests"""
from apps.vod.models import M3UEpisodeRelation
user = get_object_or_404(User, username=username)
custom_properties = (
json.loads(user.custom_properties) if user.custom_properties else {}
)
if "xc_password" not in custom_properties:
return JsonResponse({"error": "Invalid credentials"}, status=401)
if custom_properties["xc_password"] != password:
return JsonResponse({"error": "Invalid credentials"}, status=401)
# Get episode relation based on user access level
filters = {"stream_id": stream_id, "m3u_account__is_active": True}
if user.user_level < 10:
# For regular users, filter by accessible M3U accounts
if user.channel_profiles.count() > 0:
channel_profiles = user.channel_profiles.all()
from apps.m3u.models import M3UAccount
m3u_accounts = M3UAccount.objects.filter(
is_active=True,
profiles__in=channel_profiles
).distinct()
filters["m3u_account__in"] = m3u_accounts
else:
return JsonResponse({"error": "No accessible content"}, status=403)
try:
episode_relation = M3UEpisodeRelation.objects.select_related('episode').get(**filters)
except M3UEpisodeRelation.DoesNotExist:
return JsonResponse({"error": "Episode not found"}, status=404)
# Redirect to the VOD proxy endpoint
from django.http import HttpResponseRedirect
from django.urls import reverse
vod_url = reverse('proxy:vod_proxy:vod_stream', kwargs={
'content_type': 'episode',
'content_id': episode_relation.episode.uuid
})
return HttpResponseRedirect(vod_url)

View file

@ -9,6 +9,7 @@ from drf_yasg import openapi
from .routing import websocket_urlpatterns
from apps.output.views import xc_player_api, xc_panel_api, xc_get, xc_xmltv
from apps.proxy.ts_proxy.views import stream_xc
from apps.output.views import xc_movie_stream, xc_series_stream
# Define schema_view for Swagger
schema_view = get_schema_view(
@ -55,6 +56,17 @@ urlpatterns = [
stream_xc,
name="xc_stream_endpoint",
),
# XC VOD endpoints
path(
"movie/<str:username>/<str:password>/<str:stream_id>.<str:extension>",
xc_movie_stream,
name="xc_movie_stream",
),
path(
"series/<str:username>/<str:password>/<str:stream_id>.<str:extension>",
xc_series_stream,
name="xc_series_stream",
),
# Swagger UI
path(
"swagger/",