From a332678cfbcb01aa292d7e32d65deff5320bed81 Mon Sep 17 00:00:00 2001 From: SergeantPanda Date: Fri, 8 Aug 2025 08:06:28 -0500 Subject: [PATCH] Remove URL from episode relation table. --- apps/output/views.py | 4 ++-- apps/proxy/vod_proxy/views.py | 6 +++--- apps/vod/models.py | 14 ++++++++++++-- apps/vod/tasks.py | 10 ---------- core/xtream_codes.py | 20 ++++++++------------ 5 files changed, 25 insertions(+), 29 deletions(-) diff --git a/apps/output/views.py b/apps/output/views.py index ba1bccef..4fa49c81 100644 --- a/apps/output/views.py +++ b/apps/output/views.py @@ -1244,7 +1244,7 @@ def xc_get_series_info(request, user, series_id): "title": episode.name, "container_extension": relation.container_extension or "mp4", "info": { - "air_date": f"{episode.release_date}" if episode.release_date else "", + "air_date": f"{episode.air_date}" if episode.air_date else "", "crew": "", "directed_by": "", "episode_num": episode.episode_number or 0, @@ -1258,7 +1258,7 @@ def xc_get_series_info(request, user, series_id): "vote_average": float(episode.rating or 0), "vote_count": 0, "writer": "", - "release_date": f"{episode.release_date}" if episode.release_date else "", + "release_date": f"{episode.air_date}" if episode.air_date else "", "duration_secs": (episode.duration or 0) * 60, "duration": f"{episode.duration or 0} min", "video": {}, diff --git a/apps/proxy/vod_proxy/views.py b/apps/proxy/vod_proxy/views.py index 9b2b1add..4af3af5b 100644 --- a/apps/proxy/vod_proxy/views.py +++ b/apps/proxy/vod_proxy/views.py @@ -209,16 +209,16 @@ class VODStreamView(View): m3u_account=m3u_profile.m3u_account ).first() if relation: - original_url = relation.url + original_url = relation.url if hasattr(relation, 'url') else relation.get_stream_url() elif hasattr(content_obj, 'series'): # This is an Episode, get URL from episode relation - from .models import M3UEpisodeRelation + from apps.vod.models import M3UEpisodeRelation relation = M3UEpisodeRelation.objects.filter( episode=content_obj, m3u_account=m3u_profile.m3u_account ).first() if relation: - original_url = relation.url + original_url = relation.get_stream_url() if not original_url: logger.error("No URL found for content object") diff --git a/apps/vod/models.py b/apps/vod/models.py index 092e0034..e53f8c5b 100644 --- a/apps/vod/models.py +++ b/apps/vod/models.py @@ -204,7 +204,6 @@ class M3UEpisodeRelation(models.Model): episode = models.ForeignKey(Episode, on_delete=models.CASCADE, related_name='m3u_relations') # Streaming information (provider-specific) - url = models.URLField(max_length=2048) stream_id = models.CharField(max_length=255, help_text="External stream ID from M3U provider") container_extension = models.CharField(max_length=10, blank=True, null=True) @@ -225,4 +224,15 @@ class M3UEpisodeRelation(models.Model): def get_stream_url(self): """Get the full stream URL for this episode from this provider""" - return self.url + from core.xtream_codes import Client as XtreamCodesClient + + if self.m3u_account.account_type == 'XC': + # For XtreamCodes accounts, build the URL dynamically + server_url = self.m3u_account.server_url.rstrip('/') + username = self.m3u_account.username + password = self.m3u_account.password + return f"{server_url}/series/{username}/{password}/{self.stream_id}.{self.container_extension or 'mp4'}" + else: + # We might support non XC accounts in the future + # For now, return None + return None diff --git a/apps/vod/tasks.py b/apps/vod/tasks.py index e37b6892..529125d3 100644 --- a/apps/vod/tasks.py +++ b/apps/vod/tasks.py @@ -368,22 +368,12 @@ def process_episode(account, series, episode_data, season_number): } ) - # Create stream URL - with XtreamCodesClient( - account.server_url, - account.username, - account.password, - account.get_user_agent().user_agent - ) as client: - stream_url = client.get_episode_stream_url(episode_id) - # Create or update episode relation relation, created = M3UEpisodeRelation.objects.update_or_create( m3u_account=account, episode=episode, defaults={ 'stream_id': str(episode_id), - 'url': stream_url, 'container_extension': episode_data.get('container_extension', 'mp4'), 'custom_properties': { 'info': episode_data, diff --git a/core/xtream_codes.py b/core/xtream_codes.py index 0d02d1f8..469f3a9c 100644 --- a/core/xtream_codes.py +++ b/core/xtream_codes.py @@ -196,6 +196,14 @@ class Client: """Get the playback URL for a stream""" return f"{self.server_url}/live/{self.username}/{self.password}/{stream_id}.ts" + def get_episode_stream_url(self, stream_id, container_extension='mp4'): + """Get the playback URL for an episode stream""" + return f"{self.server_url}/series/{self.username}/{self.password}/{stream_id}.{container_extension}" + + def get_vod_stream_url(self, stream_id, container_extension='mp4'): + """Get the playback URL for a VOD stream""" + return f"{self.server_url}/movie/{self.username}/{self.password}/{stream_id}.{container_extension}" + def get_vod_categories(self): """Get VOD categories""" try: @@ -366,18 +374,6 @@ class Client: logger.error(traceback.format_exc()) raise - def get_vod_stream_url(self, vod_id, container_extension="mp4"): - """Get the playback URL for a VOD""" - return f"{self.server_url}/movie/{self.username}/{self.password}/{vod_id}.{container_extension}" - - def get_movie_stream_url(self, vod_id, container_extension="mp4"): - """Get the playback URL for a movie (alias for get_vod_stream_url)""" - return self.get_vod_stream_url(vod_id, container_extension) - - def get_episode_stream_url(self, episode_id, container_extension="mp4"): - """Get the playback URL for an episode""" - return f"{self.server_url}/series/{self.username}/{self.password}/{episode_id}.{container_extension}" - def close(self): """Close the session and cleanup resources""" if hasattr(self, 'session') and self.session: