This commit is contained in:
Dark1291 2025-02-05 12:45:04 +01:00
parent 1ede152923
commit f7aee0e922
18 changed files with 149 additions and 100 deletions

View File

@ -61,8 +61,8 @@ def download_film(select_title: MediaItem) -> str:
# Download the film using the m3u8 playlist, and output filename # Download the film using the m3u8 playlist, and output filename
r_proc = HLS_Downloader( r_proc = HLS_Downloader(
m3u8_playlist=master_playlist, m3u8_url=master_playlist,
output_filename=os.path.join(mp4_path, title_name) output_path=os.path.join(mp4_path, title_name)
).start() ).start()
if TELEGRAM_BOT: if TELEGRAM_BOT:

View File

@ -49,8 +49,8 @@ def download_film(select_title: MediaItem) -> str:
# Download the film using the m3u8 playlist, and output filename # Download the film using the m3u8 playlist, and output filename
r_proc = HLS_Downloader( r_proc = HLS_Downloader(
m3u8_playlist=master_playlist, m3u8_url=master_playlist,
output_filename=os.path.join(mp4_path, title_name) output_path=os.path.join(mp4_path, title_name)
).start() ).start()
if "error" in r_proc.keys(): if "error" in r_proc.keys():

View File

@ -58,8 +58,8 @@ def download_video(index_season_selected: int, index_episode_selected: int, scap
# Download the film using the m3u8 playlist, and output filename # Download the film using the m3u8 playlist, and output filename
r_proc = HLS_Downloader( r_proc = HLS_Downloader(
m3u8_playlist=master_playlist, m3u8_url=master_playlist,
output_filename=os.path.join(mp4_path, mp4_name) output_path=os.path.join(mp4_path, mp4_name)
).start() ).start()
@ -69,7 +69,7 @@ def download_video(index_season_selected: int, index_episode_selected: int, scap
except: except:
pass pass
return r_proc['path'] return r_proc['path'], r_proc['stopped']
def download_episode(scape_info_serie: GetSerieInfo, index_season_selected: int, download_all: bool = False) -> None: def download_episode(scape_info_serie: GetSerieInfo, index_season_selected: int, download_all: bool = False) -> None:
@ -91,7 +91,11 @@ def download_episode(scape_info_serie: GetSerieInfo, index_season_selected: int,
# Download all episodes without asking # Download all episodes without asking
for i_episode in range(1, episodes_count + 1): for i_episode in range(1, episodes_count + 1):
download_video(index_season_selected, i_episode, scape_info_serie) path, stopped = download_video(index_season_selected, i_episode, scape_info_serie)
if stopped:
break
console.print(f"\n[red]End downloaded [yellow]season: [red]{index_season_selected}.") console.print(f"\n[red]End downloaded [yellow]season: [red]{index_season_selected}.")
else: else:
@ -107,11 +111,11 @@ def download_episode(scape_info_serie: GetSerieInfo, index_season_selected: int,
return return
# Download selected episodes # Download selected episodes
stopped = bool(False)
for i_episode in list_episode_select: for i_episode in list_episode_select:
path, stopped = download_video(index_season_selected, i_episode, scape_info_serie)
if stopped: if stopped:
break break
download_video(index_season_selected, i_episode, scape_info_serie)
def download_series(dict_serie: MediaItem) -> None: def download_series(dict_serie: MediaItem) -> None:

View File

@ -77,8 +77,8 @@ def download_film(movie_details: Json_film) -> str:
# Download the film using the m3u8 playlist, and output filename # Download the film using the m3u8 playlist, and output filename
r_proc = HLS_Downloader( r_proc = HLS_Downloader(
m3u8_playlist=master_playlist, m3u8_url=master_playlist,
output_filename=os.path.join(mp4_path, title_name) output_path=os.path.join(mp4_path, title_name)
).start() ).start()
if "error" in r_proc.keys(): if "error" in r_proc.keys():

View File

@ -66,8 +66,8 @@ def download_film(select_title: MediaItem) -> str:
# Download the film using the m3u8 playlist, and output filename # Download the film using the m3u8 playlist, and output filename
r_proc = HLS_Downloader( r_proc = HLS_Downloader(
m3u8_playlist=master_playlist, m3u8_url=master_playlist,
output_filename=os.path.join(mp4_path, title_name) output_path=os.path.join(mp4_path, title_name)
).start() ).start()
if TELEGRAM_BOT: if TELEGRAM_BOT:

View File

@ -72,8 +72,8 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
# Download the episode # Download the episode
r_proc = HLS_Downloader( r_proc = HLS_Downloader(
m3u8_playlist=master_playlist, m3u8_url=master_playlist,
output_filename=os.path.join(mp4_path, mp4_name) output_path=os.path.join(mp4_path, mp4_name)
).start() ).start()
if "error" in r_proc.keys(): if "error" in r_proc.keys():
@ -82,7 +82,7 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
except: except:
pass pass
return r_proc['path'] return r_proc['path'], r_proc['stopped']
def download_episode(index_season_selected: int, scrape_serie: ScrapeSerie, video_source: VideoSource, download_all: bool = False) -> None: def download_episode(index_season_selected: int, scrape_serie: ScrapeSerie, video_source: VideoSource, download_all: bool = False) -> None:
""" """
@ -105,7 +105,11 @@ def download_episode(index_season_selected: int, scrape_serie: ScrapeSerie, vide
# Download all episodes without asking # Download all episodes without asking
for i_episode in range(1, episodes_count + 1): for i_episode in range(1, episodes_count + 1):
download_video(index_season_selected, i_episode, scrape_serie, video_source) path, stopped = download_video(index_season_selected, i_episode, scrape_serie, video_source)
if stopped:
break
console.print(f"\n[red]End downloaded [yellow]season: [red]{index_season_selected}.") console.print(f"\n[red]End downloaded [yellow]season: [red]{index_season_selected}.")
else: else:
@ -122,7 +126,10 @@ def download_episode(index_season_selected: int, scrape_serie: ScrapeSerie, vide
# Download selected episodes if not stopped # Download selected episodes if not stopped
for i_episode in list_episode_select: for i_episode in list_episode_select:
download_video(index_season_selected, i_episode, scrape_serie, video_source)[1] path, stopped = download_video(index_season_selected, i_episode, scrape_serie, video_source)
if stopped:
break
def download_series(select_season: MediaItem, version: str) -> None: def download_series(select_season: MediaItem, version: str) -> None:
""" """

View File

@ -72,6 +72,7 @@ class HLSClient:
response = client.get(url) response = client.get(url)
response.raise_for_status() response.raise_for_status()
return response.content if return_content else response.text return response.content if return_content else response.text
except Exception as e: except Exception as e:
logging.error(f"Attempt {attempt+1} failed: {str(e)}") logging.error(f"Attempt {attempt+1} failed: {str(e)}")
time.sleep(1.5 ** attempt) time.sleep(1.5 ** attempt)
@ -100,8 +101,10 @@ class PathManager:
root = config_manager.get('DEFAULT', 'root_path') root = config_manager.get('DEFAULT', 'root_path')
hash_name = compute_sha1_hash(self.m3u8_url) + ".mp4" hash_name = compute_sha1_hash(self.m3u8_url) + ".mp4"
return os.path.join(root, "undefined", hash_name) return os.path.join(root, "undefined", hash_name)
if not path.endswith(".mp4"): if not path.endswith(".mp4"):
path += ".mp4" path += ".mp4"
return os_manager.get_sanitize_path(path) return os_manager.get_sanitize_path(path)
def setup_directories(self): def setup_directories(self):
@ -112,7 +115,6 @@ class PathManager:
def move_final_file(self, final_file: str): def move_final_file(self, final_file: str):
"""Moves the final merged file to the desired output location.""" """Moves the final merged file to the desired output location."""
os.makedirs(os.path.dirname(self.output_path), exist_ok=True)
if os.path.exists(self.output_path): if os.path.exists(self.output_path):
os.remove(self.output_path) os.remove(self.output_path)
shutil.move(final_file, self.output_path) shutil.move(final_file, self.output_path)
@ -144,6 +146,7 @@ class M3U8Manager:
content = self.client.request(self.m3u8_url) content = self.client.request(self.m3u8_url)
if not content: if not content:
raise ValueError("Failed to fetch M3U8 content") raise ValueError("Failed to fetch M3U8 content")
self.parser.parse_data(uri=self.m3u8_url, raw_content=content) self.parser.parse_data(uri=self.m3u8_url, raw_content=content)
self.url_fixer.set_playlist(self.m3u8_url) self.url_fixer.set_playlist(self.m3u8_url)
self.is_master = self.parser.is_master_playlist self.is_master = self.parser.is_master_playlist
@ -245,49 +248,78 @@ class DownloadManager:
self.client = client self.client = client
self.url_fixer = url_fixer self.url_fixer = url_fixer
self.missing_segments = [] self.missing_segments = []
self.stopped = False
def download_video(self, video_url: str): def download_video(self, video_url: str):
"""Downloads video segments from the M3U8 playlist.""" """Downloads video segments from the M3U8 playlist."""
video_full_url = self.url_fixer.generate_full_url(video_url) video_full_url = self.url_fixer.generate_full_url(video_url)
video_tmp_dir = os.path.join(self.temp_dir, 'video') video_tmp_dir = os.path.join(self.temp_dir, 'video')
downloader = M3U8_Segments(url=video_full_url, tmp_folder=video_tmp_dir) downloader = M3U8_Segments(url=video_full_url, tmp_folder=video_tmp_dir)
result = downloader.download_streams("Video", "video") result = downloader.download_streams("Video", "video")
self.missing_segments.append(result) self.missing_segments.append(result)
if result.get('stopped', False):
self.stopped = True
return self.stopped
def download_audio(self, audio: Dict): def download_audio(self, audio: Dict):
"""Downloads audio segments for a specific language track.""" """Downloads audio segments for a specific language track."""
if self.stopped:
return True
audio_full_url = self.url_fixer.generate_full_url(audio['uri']) audio_full_url = self.url_fixer.generate_full_url(audio['uri'])
audio_tmp_dir = os.path.join(self.temp_dir, 'audio', audio['language']) audio_tmp_dir = os.path.join(self.temp_dir, 'audio', audio['language'])
downloader = M3U8_Segments(url=audio_full_url, tmp_folder=audio_tmp_dir) downloader = M3U8_Segments(url=audio_full_url, tmp_folder=audio_tmp_dir)
result = downloader.download_streams(f"Audio {audio['language']}", "audio") result = downloader.download_streams(f"Audio {audio['language']}", "audio")
self.missing_segments.append(result) self.missing_segments.append(result)
if result.get('stopped', False):
self.stopped = True
return self.stopped
def download_subtitle(self, sub: Dict): def download_subtitle(self, sub: Dict):
"""Downloads and saves subtitle file for a specific language.""" """Downloads and saves subtitle file for a specific language."""
if self.stopped:
return True
content = self.client.request(sub['uri']) content = self.client.request(sub['uri'])
if content: if content:
sub_path = os.path.join(self.temp_dir, 'subs', f"{sub['language']}.vtt") sub_path = os.path.join(self.temp_dir, 'subs', f"{sub['language']}.vtt")
with open(sub_path, 'w', encoding='utf-8') as f: with open(sub_path, 'w', encoding='utf-8') as f:
f.write(content) f.write(content)
return self.stopped
def download_all(self, video_url: str, audio_streams: List[Dict], sub_streams: List[Dict]): def download_all(self, video_url: str, audio_streams: List[Dict], sub_streams: List[Dict]):
""" """
Downloads all selected streams (video, audio, subtitles). Downloads all selected streams (video, audio, subtitles).
Skips already downloaded content to support resume functionality.
""" """
video_file = os.path.join(self.temp_dir, 'video', '0.ts') video_file = os.path.join(self.temp_dir, 'video', '0.ts')
if not os.path.exists(video_file): if not os.path.exists(video_file):
self.download_video(video_url) if self.download_video(video_url):
return True
for audio in audio_streams: for audio in audio_streams:
if self.stopped:
break
audio_file = os.path.join(self.temp_dir, 'audio', audio['language'], '0.ts') audio_file = os.path.join(self.temp_dir, 'audio', audio['language'], '0.ts')
if not os.path.exists(audio_file): if not os.path.exists(audio_file):
self.download_audio(audio) if self.download_audio(audio):
return True
for sub in sub_streams: for sub in sub_streams:
if self.stopped:
break
sub_file = os.path.join(self.temp_dir, 'subs', f"{sub['language']}.vtt") sub_file = os.path.join(self.temp_dir, 'subs', f"{sub['language']}.vtt")
if not os.path.exists(sub_file): if not os.path.exists(sub_file):
self.download_subtitle(sub) if self.download_subtitle(sub):
return True
return self.stopped
class MergeManager: class MergeManager:
@ -324,12 +356,14 @@ class MergeManager:
out_path=os.path.join(self.temp_dir, 'video.mp4'), out_path=os.path.join(self.temp_dir, 'video.mp4'),
codec=self.parser.codec codec=self.parser.codec
) )
else: else:
if MERGE_AUDIO and self.audio_streams: if MERGE_AUDIO and self.audio_streams:
audio_tracks = [{ audio_tracks = [{
'path': os.path.join(self.temp_dir, 'audio', a['language'], '0.ts'), 'path': os.path.join(self.temp_dir, 'audio', a['language'], '0.ts'),
'name': a['language'] 'name': a['language']
} for a in self.audio_streams] } for a in self.audio_streams]
merged_audio_path = os.path.join(self.temp_dir, 'merged_audio.mp4') merged_audio_path = os.path.join(self.temp_dir, 'merged_audio.mp4')
merged_file = join_audios( merged_file = join_audios(
video_path=video_file, video_path=video_file,
@ -337,17 +371,20 @@ class MergeManager:
out_path=merged_audio_path, out_path=merged_audio_path,
codec=self.parser.codec codec=self.parser.codec
) )
if MERGE_SUBTITLE and self.sub_streams: if MERGE_SUBTITLE and self.sub_streams:
sub_tracks = [{ sub_tracks = [{
'path': os.path.join(self.temp_dir, 'subs', f"{s['language']}.vtt"), 'path': os.path.join(self.temp_dir, 'subs', f"{s['language']}.vtt"),
'language': s['language'] 'language': s['language']
} for s in self.sub_streams] } for s in self.sub_streams]
merged_subs_path = os.path.join(self.temp_dir, 'final.mp4') merged_subs_path = os.path.join(self.temp_dir, 'final.mp4')
merged_file = join_subtitle( merged_file = join_subtitle(
video_path=merged_file, video_path=merged_file,
subtitles_list=sub_tracks, subtitles_list=sub_tracks,
out_path=merged_subs_path out_path=merged_subs_path
) )
return merged_file return merged_file
@ -382,7 +419,8 @@ class HLS_Downloader:
'path': self.path_manager.output_path, 'path': self.path_manager.output_path,
'url': self.m3u8_url, 'url': self.m3u8_url,
'is_master': False, 'is_master': False,
'error': 'File already exists' 'error': 'File already exists',
'stopped': False
} }
if TELEGRAM_BOT: if TELEGRAM_BOT:
bot.send_message(response) bot.send_message(response)
@ -400,12 +438,23 @@ class HLS_Downloader:
client=self.client, client=self.client,
url_fixer=self.m3u8_manager.url_fixer url_fixer=self.m3u8_manager.url_fixer
) )
self.download_manager.download_all(
# Check if download was stopped
download_stopped = self.download_manager.download_all(
video_url=self.m3u8_manager.video_url, video_url=self.m3u8_manager.video_url,
audio_streams=self.m3u8_manager.audio_streams, audio_streams=self.m3u8_manager.audio_streams,
sub_streams=self.m3u8_manager.sub_streams sub_streams=self.m3u8_manager.sub_streams
) )
if download_stopped:
return {
'path': None,
'url': self.m3u8_url,
'is_master': self.m3u8_manager.is_master,
'error': 'Download stopped by user',
'stopped': True
}
self.merge_manager = MergeManager( self.merge_manager = MergeManager(
temp_dir=self.path_manager.temp_dir, temp_dir=self.path_manager.temp_dir,
parser=self.m3u8_manager.parser, parser=self.m3u8_manager.parser,
@ -422,18 +471,21 @@ class HLS_Downloader:
return { return {
'path': self.path_manager.output_path, 'path': self.path_manager.output_path,
'url': self.m3u8_url, 'url': self.m3u8_url,
'is_master': self.m3u8_manager.is_master 'is_master': self.m3u8_manager.is_master,
'stopped': False
} }
except Exception as e: except Exception as e:
error_msg = str(e) error_msg = str(e)
console.print(f"[red]Download failed: {error_msg}[/red]") console.print(f"[red]Download failed: {error_msg}[/red]")
logging.error("Download error", exc_info=True) logging.error("Download error", exc_info=True)
return { return {
'path': None, 'path': None,
'url': self.m3u8_url, 'url': self.m3u8_url,
'is_master': getattr(self.m3u8_manager, 'is_master', None), 'is_master': getattr(self.m3u8_manager, 'is_master', None),
'error': error_msg 'error': error_msg,
'stopped': False
} }
def _print_summary(self): def _print_summary(self):
@ -466,6 +518,7 @@ class HLS_Downloader:
if missing_ts: if missing_ts:
panel_content += f"\n{missing_info}" panel_content += f"\n{missing_info}"
os.rename(self.path_manager.output_path, self.path_manager.output_path.replace(".mp4", "_failed.mp4")) os.rename(self.path_manager.output_path, self.path_manager.output_path.replace(".mp4", "_failed.mp4"))
console.print(Panel( console.print(Panel(
panel_content, panel_content,
title=f"{os.path.basename(self.path_manager.output_path.replace('.mp4', ''))}", title=f"{os.path.basename(self.path_manager.output_path.replace('.mp4', ''))}",

View File

@ -47,7 +47,6 @@ PROXY_START_MAX = config_manager.get_float('REQUESTS', 'proxy_start_max')
DEFAULT_VIDEO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_video_workser') DEFAULT_VIDEO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_video_workser')
DEFAULT_AUDIO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_audio_workser') DEFAULT_AUDIO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_audio_workser')
MAX_TIMEOOUT = config_manager.get_int("REQUESTS", "timeout") MAX_TIMEOOUT = config_manager.get_int("REQUESTS", "timeout")
TELEGRAM_BOT = config_manager.get_bool('DEFAULT', 'telegram_bot')
@ -70,7 +69,7 @@ class M3U8_Segments:
# Util class # Util class
self.decryption: M3U8_Decryption = None self.decryption: M3U8_Decryption = None
self.class_ts_estimator = M3U8_Ts_Estimator(0) self.class_ts_estimator = M3U8_Ts_Estimator(0, self)
self.class_url_fixer = M3U8_UrlFix(url) self.class_url_fixer = M3U8_UrlFix(url)
# Sync # Sync
@ -88,6 +87,8 @@ class M3U8_Segments:
self.info_maxRetry = 0 self.info_maxRetry = 0
self.info_nRetry = 0 self.info_nRetry = 0
self.info_nFailed = 0 self.info_nFailed = 0
self.active_retries = 0
self.active_retries_lock = threading.Lock()
def __get_key__(self, m3u8_parser: M3U8_Parser) -> bytes: def __get_key__(self, m3u8_parser: M3U8_Parser) -> bytes:
key_uri = urljoin(self.url, m3u8_parser.keys.get('uri')) key_uri = urljoin(self.url, m3u8_parser.keys.get('uri'))
@ -232,11 +233,18 @@ class M3U8_Segments:
self.queue.put((index, None)) # Marker for failed segment self.queue.put((index, None)) # Marker for failed segment
progress_bar.update(1) progress_bar.update(1)
self.info_nFailed += 1 self.info_nFailed += 1
return
with self.active_retries_lock:
self.active_retries += 1
sleep_time = backoff_factor * (2 ** attempt) sleep_time = backoff_factor * (2 ** attempt)
logging.info(f"Retrying segment {index} in {sleep_time} seconds...") logging.info(f"Retrying segment {index} in {sleep_time} seconds...")
time.sleep(sleep_time) time.sleep(sleep_time)
with self.active_retries_lock:
self.active_retries -= 1
def write_segments_to_file(self): def write_segments_to_file(self):
""" """
Writes segments to file with additional verification. Writes segments to file with additional verification.
@ -296,11 +304,7 @@ class M3U8_Segments:
- description: Description to insert on tqdm bar - description: Description to insert on tqdm bar
- type (str): Type of download: 'video' or 'audio' - type (str): Type of download: 'video' or 'audio'
""" """
self.get_info()
if TELEGRAM_BOT:
# Viene usato per lo screen
console.log("####")
self.setup_interrupt_handler() self.setup_interrupt_handler()
progress_bar = tqdm( progress_bar = tqdm(

View File

@ -110,6 +110,8 @@ def join_video(video_path: str, out_path: str, codec: M3U8_Codec = None):
capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join video") capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join video")
print() print()
return out_path
def join_audios(video_path: str, audio_tracks: List[Dict[str, str]], out_path: str, codec: M3U8_Codec = None): def join_audios(video_path: str, audio_tracks: List[Dict[str, str]], out_path: str, codec: M3U8_Codec = None):
""" """
@ -204,6 +206,8 @@ def join_audios(video_path: str, audio_tracks: List[Dict[str, str]], out_path: s
capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join audio") capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join audio")
print() print()
return out_path
def join_subtitle(video_path: str, subtitles_list: List[Dict[str, str]], out_path: str): def join_subtitle(video_path: str, subtitles_list: List[Dict[str, str]], out_path: str):
""" """
@ -256,3 +260,5 @@ def join_subtitle(video_path: str, subtitles_list: List[Dict[str, str]], out_pat
with suppress_output(): with suppress_output():
capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join subtitle") capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join subtitle")
print() print()
return out_path

View File

@ -22,7 +22,7 @@ TQDM_USE_LARGE_BAR = not ("android" in sys.platform or "ios" in sys.platform)
class M3U8_Ts_Estimator: class M3U8_Ts_Estimator:
def __init__(self, total_segments: int): def __init__(self, total_segments: int, segments_instance=None):
""" """
Initialize the M3U8_Ts_Estimator object. Initialize the M3U8_Ts_Estimator object.
@ -32,6 +32,7 @@ class M3U8_Ts_Estimator:
self.ts_file_sizes = [] self.ts_file_sizes = []
self.now_downloaded_size = 0 self.now_downloaded_size = 0
self.total_segments = total_segments self.total_segments = total_segments
self.segments_instance = segments_instance
self.lock = threading.Lock() self.lock = threading.Lock()
self.speed = {"upload": "N/A", "download": "N/A"} self.speed = {"upload": "N/A", "download": "N/A"}
@ -102,7 +103,6 @@ class M3U8_Ts_Estimator:
return "Error" return "Error"
def update_progress_bar(self, total_downloaded: int, duration: float, progress_counter: tqdm) -> None: def update_progress_bar(self, total_downloaded: int, duration: float, progress_counter: tqdm) -> None:
"""Updates the progress bar with download information."""
try: try:
self.add_ts_file(total_downloaded * self.total_segments, total_downloaded, duration) self.add_ts_file(total_downloaded * self.total_segments, total_downloaded, duration)
@ -120,21 +120,25 @@ class M3U8_Ts_Estimator:
if len(speed_data) >= 2: if len(speed_data) >= 2:
average_internet_speed = speed_data[0] average_internet_speed = speed_data[0]
average_internet_unit = speed_data[1] average_internet_unit = speed_data[1]
else: else:
average_internet_speed = "N/A" average_internet_speed = "N/A"
average_internet_unit = "" average_internet_unit = ""
# Retrieve retry count from segments_instance
retry_count = self.segments_instance.active_retries if self.segments_instance else 0
progress_str = ( progress_str = (
f"{Colors.WHITE}[ {Colors.GREEN}{number_file_downloaded} {Colors.WHITE}< " f"{Colors.WHITE}[ {Colors.GREEN}{number_file_downloaded} {Colors.WHITE}< "
f"{Colors.GREEN}{number_file_total_size} {Colors.RED}{units_file_total_size} " f"{Colors.GREEN}{number_file_total_size} {Colors.RED}{units_file_total_size} "
f"{Colors.WHITE}| {Colors.CYAN}{average_internet_speed} {Colors.RED}{average_internet_unit}" f"{Colors.WHITE}| {Colors.CYAN}{average_internet_speed} {Colors.RED}{average_internet_unit} "
f"{Colors.WHITE}| {Colors.GREEN}CRR {Colors.RED}{retry_count}"
) )
else: else:
# Retrieve retry count from segments_instance
retry_count = self.segments_instance.active_retries if self.segments_instance else 0
progress_str = ( progress_str = (
f"{Colors.WHITE}[ {Colors.GREEN}{number_file_downloaded} {Colors.WHITE}< " f"{Colors.WHITE}[ {Colors.GREEN}{number_file_downloaded} {Colors.WHITE}< "
f"{Colors.GREEN}{number_file_total_size} {Colors.RED}{units_file_total_size}" f"{Colors.GREEN}{number_file_total_size} {Colors.RED}{units_file_total_size} "
f"{Colors.WHITE}| {Colors.GREEN}CRR {Colors.RED}{retry_count}"
) )
progress_counter.set_postfix_str(progress_str) progress_counter.set_postfix_str(progress_str)

View File

@ -17,7 +17,7 @@ class RequestManager:
if not hasattr(self, 'initialized'): if not hasattr(self, 'initialized'):
self.json_file = json_file self.json_file = json_file
self.initialized = True self.initialized = True
self.on_response_callback = None # Aggiungi un campo per il callback self.on_response_callback = None
def create_request(self, type: str) -> str: def create_request(self, type: str) -> str:
request_data = { request_data = {

View File

@ -6,40 +6,26 @@ import json
session_data = {} session_data = {}
def set_session(value): def set_session(value):
"""
Salva lo script_id nella sessione.
"""
session_data['script_id'] = value session_data['script_id'] = value
def get_session(): def get_session():
"""
Restituisce lo script_id dalla sessione, o 'unknown' se non presente.
"""
return session_data.get('script_id', 'unknown') return session_data.get('script_id', 'unknown')
def updateScriptId(screen_id, titolo):
def update_script_id(screen_id, titolo):
"""
Aggiorna il titolo di uno script in base allo screen_id.
"""
json_file = "scripts.json" json_file = "scripts.json"
try: try:
# Apre il file JSON e carica i dati
with open(json_file, 'r') as f: with open(json_file, 'r') as f:
scripts_data = json.load(f) scripts_data = json.load(f)
except FileNotFoundError: except FileNotFoundError:
scripts_data = [] scripts_data = []
# Cerca lo script con lo screen_id corrispondente # cerco lo script con lo screen_id
for script in scripts_data: for script in scripts_data:
if script["screen_id"] == screen_id: if script["screen_id"] == screen_id:
# se trovo il match, aggiorno il titolo
# Se trovato, aggiorna il titolo
script["titolo"] = titolo script["titolo"] = titolo
# Salva i dati aggiornati nel file JSON # aggiorno il file json
with open(json_file, 'w') as f: with open(json_file, 'w') as f:
json.dump(scripts_data, f, indent=4) json.dump(scripts_data, f, indent=4)
@ -47,26 +33,20 @@ def update_script_id(screen_id, titolo):
print(f"Screen_id {screen_id} non trovato.") print(f"Screen_id {screen_id} non trovato.")
def deleteScriptId(screen_id):
def delete_script_id(screen_id):
"""
Elimina uno script in base allo screen_id.
"""
json_file = "scripts.json" json_file = "scripts.json"
try: try:
with open(json_file, 'r') as f: with open(json_file, 'r') as f:
scripts_data = json.load(f) scripts_data = json.load(f)
except FileNotFoundError: except FileNotFoundError:
scripts_data = [] scripts_data = []
# Cerca lo script con lo screen_id corrispondente
for script in scripts_data: for script in scripts_data:
if script["screen_id"] == screen_id: if script["screen_id"] == screen_id:
# se trovo il match, elimino lo script
# Se trovato, rimuove lo script
scripts_data.remove(script) scripts_data.remove(script)
# aggiorno il file json
with open(json_file, 'w') as f: with open(json_file, 'w') as f:
json.dump(scripts_data, f, indent=4) json.dump(scripts_data, f, indent=4)

View File

@ -559,18 +559,3 @@ class TelegramBot:
def get_bot_instance(): def get_bot_instance():
return TelegramBot.get_instance() return TelegramBot.get_instance()
# Esempio di utilizzo
if __name__ == "__main__":
# Usa le variabili
token = os.getenv("TOKEN_TELEGRAM")
authorized_user_id = os.getenv("AUTHORIZED_USER_ID")
TOKEN = token
AUTHORIZED_USER_ID = int(authorized_user_id)
# Inizializza il bot
bot = TelegramBot.init_bot(TOKEN, AUTHORIZED_USER_ID)
bot.run()

View File

@ -25,8 +25,7 @@ def update():
""" """
Check for updates on GitHub and display relevant information. Check for updates on GitHub and display relevant information.
""" """
console.print("\n[cyan]→ [green]Checking GitHub version ...")
console.print("[green]Checking GitHub version [white]...")
# Make the GitHub API requests and handle potential errors # Make the GitHub API requests and handle potential errors
try: try:
@ -59,7 +58,7 @@ def update():
if str(__version__).replace('v', '') != str(last_version).replace('v', '') : if str(__version__).replace('v', '') != str(last_version).replace('v', '') :
console.print(f"[red]New version available: [yellow]{last_version} \n") console.print(f"[red]New version available: [yellow]{last_version} \n")
else: else:
console.print(f" [yellow]Everything is up to date \n") console.print(f" [red]Everything is up to date \n")
console.print(f"[red]{__title__} has been downloaded [yellow]{total_download_count} [red]times, but only [yellow]{percentual_stars}% [red]of users have starred it.\n\ console.print(f"[red]{__title__} has been downloaded [yellow]{total_download_count} [red]times, but only [yellow]{percentual_stars}% [red]of users have starred it.\n\
[cyan]Help the repository grow today by leaving a [yellow]star [cyan]and [yellow]sharing [cyan]it with others online!") [cyan]Help the repository grow today by leaving a [yellow]star [cyan]and [yellow]sharing [cyan]it with others online!")

View File

@ -492,7 +492,7 @@ class OsSummary:
else: else:
logging.info(f"Library: {installed_version}") logging.info(f"Library: {installed_version}")
console.print(f"[cyan]Libraries[white]: [bold red]{', '.join([self.get_library_version(lib) for lib in optional_libraries])}[/bold red]\n") #console.print(f"[cyan]Libraries[white]: [bold red]{', '.join([self.get_library_version(lib) for lib in optional_libraries])}[/bold red]\n")
logging.info(f"Libraries: {', '.join([self.get_library_version(lib) for lib in optional_libraries])}") logging.info(f"Libraries: {', '.join([self.get_library_version(lib) for lib in optional_libraries])}")

View File

@ -20,6 +20,6 @@ from StreamingCommunity.Lib.Downloader import HLS_Downloader
start_message() start_message()
logger = Logger() logger = Logger()
print("Return: ", HLS_Downloader( print("Return: ", HLS_Downloader(
output_filename="test.mp4", output_path="test.mp4",
m3u8_playlist="https://acdn.ak-stream-videoplatform.sky.it/hls/2024/11/21/968275/master.m3u8" m3u8_url="https://acdn.ak-stream-videoplatform.sky.it/hls/2024/11/21/968275/master.m3u8"
).start()) ).start())

View File

@ -3,7 +3,7 @@
"debug": false, "debug": false,
"log_file": "app.log", "log_file": "app.log",
"log_to_file": false, "log_to_file": false,
"show_message": false, "show_message": true,
"clean_console": true, "clean_console": true,
"root_path": "Video", "root_path": "Video",
"movie_folder_name": "Movie", "movie_folder_name": "Movie",
@ -28,7 +28,7 @@
"proxy_start_max": 0.5 "proxy_start_max": 0.5
}, },
"M3U8_DOWNLOAD": { "M3U8_DOWNLOAD": {
"tqdm_delay": 0.15, "tqdm_delay": 0.12,
"default_video_workser": 12, "default_video_workser": 12,
"default_audio_workser": 12, "default_audio_workser": 12,
"merge_audio": true, "merge_audio": true,

View File

@ -2,13 +2,20 @@
import sys import sys
from StreamingCommunity.run import main from StreamingCommunity.run import main
from StreamingCommunity.Util._jsonConfig import config_manager
from StreamingCommunity.TelegramHelp.request_manager import RequestManager from StreamingCommunity.TelegramHelp.request_manager import RequestManager
from StreamingCommunity.TelegramHelp.session import set_session from StreamingCommunity.TelegramHelp.session import set_session
# Svuoto il file # Svuoto il file
request_manager = RequestManager() TELEGRAM_BOT = config_manager.get_bool('DEFAULT', 'telegram_bot')
request_manager.clear_file()
script_id = sys.argv[1] if len(sys.argv) > 1 else "unknown"
set_session(script_id) if TELEGRAM_BOT:
main(script_id) request_manager = RequestManager()
request_manager.clear_file()
script_id = sys.argv[1] if len(sys.argv) > 1 else "unknown"
set_session(script_id)
main(script_id)
else:
main(0)