diff --git a/StreamingCommunity/Api/Site/ddlstreamitaly/series.py b/StreamingCommunity/Api/Site/ddlstreamitaly/series.py index 95a4078..ec18bf1 100644 --- a/StreamingCommunity/Api/Site/ddlstreamitaly/series.py +++ b/StreamingCommunity/Api/Site/ddlstreamitaly/series.py @@ -39,7 +39,6 @@ def download_video(index_episode_selected: int, scape_info_serie: GetSerieInfo, Return: - str: output path """ - start_message() # Get info about episode diff --git a/StreamingCommunity/Api/Site/guardaserie/series.py b/StreamingCommunity/Api/Site/guardaserie/series.py index cd8ef67..70d8fa0 100644 --- a/StreamingCommunity/Api/Site/guardaserie/series.py +++ b/StreamingCommunity/Api/Site/guardaserie/series.py @@ -13,7 +13,7 @@ from StreamingCommunity.Lib.Downloader import HLS_Downloader # Logic class -from StreamingCommunity.Api.Template.Util import manage_selection, map_episode_title, validate_selection, validate_episode_selection, execute_search +from StreamingCommunity.Api.Template.Util import manage_selection, map_episode_title, dynamic_format_number, validate_selection, validate_episode_selection, execute_search from StreamingCommunity.Api.Template.Class.SearchType import MediaItem @@ -39,8 +39,8 @@ def download_video(index_season_selected: int, index_episode_selected: int, scap Return: - str: output path """ - start_message() + index_season_selected = dynamic_format_number(index_season_selected) # Get info about episode obj_episode = scape_info_serie.list_episodes[index_episode_selected - 1] diff --git a/StreamingCommunity/Api/Site/streamingcommunity/series.py b/StreamingCommunity/Api/Site/streamingcommunity/series.py index afb2211..36da453 100644 --- a/StreamingCommunity/Api/Site/streamingcommunity/series.py +++ b/StreamingCommunity/Api/Site/streamingcommunity/series.py @@ -15,7 +15,7 @@ from StreamingCommunity.Lib.Downloader import HLS_Downloader # Logic class from .util.ScrapeSerie import ScrapeSerie -from StreamingCommunity.Api.Template.Util import manage_selection, map_episode_title, validate_selection, validate_episode_selection, execute_search +from StreamingCommunity.Api.Template.Util import manage_selection, map_episode_title, dynamic_format_number, validate_selection, validate_episode_selection, execute_search from StreamingCommunity.Api.Template.Class.SearchType import MediaItem @@ -40,6 +40,7 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra - str: output path """ start_message() + index_season_selected = dynamic_format_number(index_season_selected) # Get info about episode obj_episode = scrape_serie.episode_manager.get(index_episode_selected - 1) diff --git a/StreamingCommunity/Api/Site/streamingcommunity/site.py b/StreamingCommunity/Api/Site/streamingcommunity/site.py index 2932b3c..19c2acb 100644 --- a/StreamingCommunity/Api/Site/streamingcommunity/site.py +++ b/StreamingCommunity/Api/Site/streamingcommunity/site.py @@ -58,7 +58,7 @@ def get_version(domain: str): # Extract version version = json.loads(soup.find("div", {"id": "app"}).get("data-page"))['version'] - console.print(f"[cyan]Get version [white]=> [red]{version} \n") + #console.print(f"[cyan]Get version [white]=> [red]{version} \n") return version diff --git a/StreamingCommunity/Api/Template/Util/__init__.py b/StreamingCommunity/Api/Template/Util/__init__.py index 88248cb..e40d729 100644 --- a/StreamingCommunity/Api/Template/Util/__init__.py +++ b/StreamingCommunity/Api/Template/Util/__init__.py @@ -2,4 +2,4 @@ from .recall_search import execute_search from .get_domain import search_domain -from .manage_ep import manage_selection, map_episode_title, validate_episode_selection, validate_selection \ No newline at end of file +from .manage_ep import manage_selection, map_episode_title, validate_episode_selection, validate_selection, dynamic_format_number \ No newline at end of file diff --git a/StreamingCommunity/Api/Template/Util/manage_ep.py b/StreamingCommunity/Api/Template/Util/manage_ep.py index b138b04..d420b13 100644 --- a/StreamingCommunity/Api/Template/Util/manage_ep.py +++ b/StreamingCommunity/Api/Template/Util/manage_ep.py @@ -89,7 +89,7 @@ def map_episode_title(tv_name: str, number_season: int, episode_number: int, epi map_episode_temp = map_episode_temp.replace("%(tv_name)", os_manager.get_sanitize_file(tv_name)) if number_season != None: - map_episode_temp = map_episode_temp.replace("%(season)", dynamic_format_number(number_season)) + map_episode_temp = map_episode_temp.replace("%(season)", number_season) else: map_episode_temp = map_episode_temp.replace("%(season)", dynamic_format_number(0)) diff --git a/StreamingCommunity/Lib/Downloader/HLS/downloader.py b/StreamingCommunity/Lib/Downloader/HLS/downloader.py index 749b316..4a004b9 100644 --- a/StreamingCommunity/Lib/Downloader/HLS/downloader.py +++ b/StreamingCommunity/Lib/Downloader/HLS/downloader.py @@ -2,6 +2,7 @@ import os import sys +import time import logging @@ -11,6 +12,7 @@ import httpx # Internal utilities from StreamingCommunity.Util._jsonConfig import config_manager +from StreamingCommunity.Util.headers import get_headers from StreamingCommunity.Util.console import console, Panel from StreamingCommunity.Util.color import Colors from StreamingCommunity.Util.os import ( @@ -45,6 +47,7 @@ MERGE_SUBTITLE = config_manager.get_bool('M3U8_DOWNLOAD', 'merge_subs') REMOVE_SEGMENTS_FOLDER = config_manager.get_bool('M3U8_DOWNLOAD', 'cleanup_tmp_folder') FILTER_CUSTOM_REOLUTION = config_manager.get_int('M3U8_PARSER', 'force_resolution') GET_ONLY_LINK = config_manager.get_bool('M3U8_PARSER', 'get_only_link') +RETRY_LIMIT = config_manager.get_int('REQUESTS', 'max_retry') # Variable @@ -470,17 +473,57 @@ class ContentDownloader: # Parse the M3U8 file to get the subtitle URI m3u8_sub_parser = M3U8_Parser() - m3u8_sub_parser.parse_data( - uri=obj_subtitle.get('uri'), - raw_content=httpx.get(obj_subtitle.get('url')).text # Fetch subtitle content - ) + url = obj_subtitle.get('url') + success = False + + for attempt in range(RETRY_LIMIT): + try: + response = httpx.get(url, headers={'user-agent': get_headers()}, timeout=20) + response.raise_for_status() + m3u8_sub_parser.parse_data( + uri=obj_subtitle.get('uri'), + raw_content=response.text + ) + success = True + break + + except httpx.RequestError as e: + logging.warning(f"Attempt {attempt + 1} failed for URL {url}: {e}") + time.sleep(2) + + if not success: + console.log(f"[red]Failed to download subtitle data for: {sub_language}") + continue # Print the status of the subtitle download - #console.print(f"[cyan]Downloading subtitle: [red]{sub_language.lower()}") + console.print(f"[cyan] - Downloading subtitle: [red]{sub_language.lower()}") + + # Download the subtitle content with retry + subtitle_content = None + for attempt in range(RETRY_LIMIT): + try: + response = httpx.get(m3u8_sub_parser.subtitle[-1], headers={'user-agent': get_headers()}, timeout=20) + response.raise_for_status() + subtitle_content = response.content + break + + except httpx.RequestError as e: + logging.warning(f"Attempt {attempt + 1} failed for subtitle content URL: {e}") + time.sleep(2) + + if subtitle_content is None: + console.log(f"[red]Failed to download subtitle content for: {sub_language}") + continue # Write the content to the specified file - with open(obj_subtitle.get("path"), "wb") as f: - f.write(HttpClient().get_content(m3u8_sub_parser.subtitle[-1])) + try: + with open(obj_subtitle.get("path"), "wb") as f: + f.write(subtitle_content) + #console.log(f"[green]Subtitle downloaded successfully: {sub_language}") + + except Exception as e: + logging.error(f"Failed to write subtitle file for {sub_language}: {e}") + #console.log(f"[red]Error writing subtitle file: {sub_language}") class ContentJoiner: