Add options [4-*]

This commit is contained in:
Lovi-0 2024-07-11 21:11:44 +02:00
parent 8c1baf929a
commit 49a8826142
13 changed files with 145 additions and 68 deletions

View File

@ -1,5 +1,6 @@
# 19.06.24 # 19.06.24
import sys
import logging import logging
from typing import List from typing import List
@ -55,9 +56,29 @@ def manage_selection(cmd_insert: str, max_count: int) -> List[int]:
# For a range (e.g., '[5-12]') # For a range (e.g., '[5-12]')
elif "[" in cmd_insert: elif "[" in cmd_insert:
start, end = map(int, cmd_insert[1:-1].split('-'))
# Extract the start and end parts
start, end = map(str.strip, cmd_insert[1:-1].split('-'))
start = int(start)
# If end is an integer, convert it
try:
end = int(end)
except ValueError:
# end remains a string if conversion fails
pass
# Generate the list_season_select based on the type of end
if isinstance(end, int):
list_season_select = list(range(start, end + 1)) list_season_select = list(range(start, end + 1))
elif end == "*":
list_season_select = list(range(start, max_count + 1))
else:
raise ValueError("Invalid end value")
# For all seasons # For all seasons
elif cmd_insert == "*": elif cmd_insert == "*":
list_season_select = list(range(1, max_count+1)) list_season_select = list(range(1, max_count+1))

View File

@ -6,7 +6,7 @@ from Src.Util.console import console, msg
# Logic class # Logic class
from .site import title_search, run_get_select_title from .site import title_search, run_get_select_title
from .anime import donwload_film, donwload_series from .anime import download_film, download_series
# Variable # Variable
@ -25,10 +25,10 @@ def search():
select_title = run_get_select_title() select_title = run_get_select_title()
if select_title.type == 'TV': if select_title.type == 'TV':
donwload_series(select_title) download_series(select_title)
else: else:
donwload_film(select_title) download_film(select_title)
else: else:
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}") console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")

View File

@ -62,7 +62,7 @@ def download_episode(index_select: int):
logging.error(f"Skip index: {index_select} cant find info with api.") logging.error(f"Skip index: {index_select} cant find info with api.")
def donwload_series(select_title: MediaItem): def download_series(select_title: MediaItem):
""" """
Function to download episodes of a TV series. Function to download episodes of a TV series.
@ -79,7 +79,7 @@ def donwload_series(select_title: MediaItem):
console.log(f"[cyan]Episodes find: [red]{episoded_count}") console.log(f"[cyan]Episodes find: [red]{episoded_count}")
# Prompt user to select an episode index # Prompt user to select an episode index
last_command = msg.ask("\n[cyan]Insert media [red]index [yellow]or [red](*) [cyan]to download all media [yellow]or [red][1-2] [cyan]for a range of media") last_command = msg.ask("\n[cyan]Insert media [red]index [yellow]or [red](*) [cyan]to download all media [yellow]or [red][1-2] [cyan]or [red][3-*] [cyan]for a range of media")
# Manage user selection # Manage user selection
list_episode_select = manage_selection(last_command, episoded_count) list_episode_select = manage_selection(last_command, episoded_count)
@ -94,7 +94,7 @@ def donwload_series(select_title: MediaItem):
download_episode(i_episode-1) download_episode(i_episode-1)
def donwload_film(select_title: MediaItem): def download_film(select_title: MediaItem):
""" """
Function to download a film. Function to download a film.

View File

@ -27,7 +27,7 @@ table_show_manager = TVShowManager()
video_source = VideoSource() video_source = VideoSource()
def donwload_video(scape_info_serie: GetSerieInfo, index_episode_selected: int) -> None: def download_video(scape_info_serie: GetSerieInfo, index_episode_selected: int) -> None:
""" """
Download a single episode video. Download a single episode video.
@ -91,12 +91,12 @@ def download_thread(dict_serie: MediaItem):
# Download selected episodes # Download selected episodes
if len(list_episode_select) == 1 and last_command != "*": if len(list_episode_select) == 1 and last_command != "*":
donwload_video(scape_info_serie, list_episode_select[0]) download_video(scape_info_serie, list_episode_select[0])
# Download all other episodes selecter # Download all other episodes selecter
else: else:
for i_episode in list_episode_select: for i_episode in list_episode_select:
donwload_video(scape_info_serie, i_episode) download_video(scape_info_serie, i_episode)
def display_episodes_list(obj_episode_manager) -> str: def display_episodes_list(obj_episode_manager) -> str:

View File

@ -26,7 +26,7 @@ table_show_manager = TVShowManager()
video_source = VideoSource() video_source = VideoSource()
def donwload_video(scape_info_serie: GetSerieInfo, index_season_selected: int, index_episode_selected: int) -> None: def download_video(scape_info_serie: GetSerieInfo, index_season_selected: int, index_episode_selected: int) -> None:
""" """
Download a single episode video. Download a single episode video.
@ -67,14 +67,14 @@ def donwload_video(scape_info_serie: GetSerieInfo, index_season_selected: int, i
).start() ).start()
def donwload_episode(scape_info_serie: GetSerieInfo, index_season_selected: int, donwload_all: bool = False) -> None: def download_episode(scape_info_serie: GetSerieInfo, index_season_selected: int, download_all: bool = False) -> None:
""" """
Download all episodes of a season. Download all episodes of a season.
Parameters: Parameters:
- tv_name (str): Name of the TV series. - tv_name (str): Name of the TV series.
- index_season_selected (int): Index of the selected season. - index_season_selected (int): Index of the selected season.
- donwload_all (bool): Donwload all seasons episodes - download_all (bool): Download all seasons episodes
""" """
# Start message and collect information about episodes # Start message and collect information about episodes
@ -83,14 +83,14 @@ def donwload_episode(scape_info_serie: GetSerieInfo, index_season_selected: int,
episodes_count = len(list_dict_episode) episodes_count = len(list_dict_episode)
# Download all episodes wihtout ask # Download all episodes wihtout ask
if donwload_all: if download_all:
for i_episode in range(1, episodes_count+1): for i_episode in range(1, episodes_count+1):
donwload_video(scape_info_serie, index_season_selected, i_episode) download_video(scape_info_serie, index_season_selected, i_episode)
console.print(f"\n[red]Download [yellow]season: [red]{index_season_selected}.") console.print(f"\n[red]Download [yellow]season: [red]{index_season_selected}.")
# If not download all episode but a single season # If not download all episode but a single season
if not donwload_all: if not download_all:
# Display episodes list and manage user selection # Display episodes list and manage user selection
last_command = display_episodes_list(scape_info_serie.list_episodes) last_command = display_episodes_list(scape_info_serie.list_episodes)
@ -98,12 +98,12 @@ def donwload_episode(scape_info_serie: GetSerieInfo, index_season_selected: int,
# Download selected episodes # Download selected episodes
if len(list_episode_select) == 1 and last_command != "*": if len(list_episode_select) == 1 and last_command != "*":
donwload_video(scape_info_serie, index_season_selected, list_episode_select[0]) download_video(scape_info_serie, index_season_selected, list_episode_select[0])
# Download all other episodes selecter # Download all other episodes selecter
else: else:
for i_episode in list_episode_select: for i_episode in list_episode_select:
donwload_video(scape_info_serie, index_season_selected, i_episode) download_video(scape_info_serie, index_season_selected, i_episode)
def download_series(dict_serie: MediaItem) -> None: def download_series(dict_serie: MediaItem) -> None:
@ -125,23 +125,23 @@ def download_series(dict_serie: MediaItem) -> None:
# Prompt user for season selection and download episodes # Prompt user for season selection and download episodes
console.print(f"\n[green]Season find: [red]{seasons_count}") console.print(f"\n[green]Season find: [red]{seasons_count}")
index_season_selected = str(msg.ask("\n[cyan]Insert media [red]index [yellow]or [red](*) [cyan]to download all media [yellow]or [red][1-2] [cyan]for a range of media")) index_season_selected = msg.ask("\n[cyan]Insert media [red]index [yellow]or [red](*) [cyan]to download all media [yellow]or [red][1-2] [cyan]or [red][3-*] [cyan]for a range of media")
list_season_select = manage_selection(index_season_selected, seasons_count) list_season_select = manage_selection(index_season_selected, seasons_count)
# Download selected episodes # Download selected episodes
if len(list_season_select) == 1 and index_season_selected != "*": if len(list_season_select) == 1 and index_season_selected != "*":
if 1 <= int(index_season_selected) <= seasons_count: if 1 <= int(index_season_selected) <= seasons_count:
donwload_episode(scape_info_serie, list_season_select[0]) download_episode(scape_info_serie, list_season_select[0])
# Dowload all seasons and episodes # Dowload all seasons and episodes
elif index_season_selected == "*": elif index_season_selected == "*":
for i_season in list_season_select: for i_season in list_season_select:
donwload_episode(scape_info_serie, i_season, True) download_episode(scape_info_serie, i_season, True)
# Download all other season selecter # Download all other season selecter
else: else:
for i_season in list_season_select: for i_season in list_season_select:
donwload_episode(scape_info_serie, i_season) download_episode(scape_info_serie, i_season)
def display_episodes_list(obj_episode_manager) -> str: def display_episodes_list(obj_episode_manager) -> str:

View File

@ -23,8 +23,8 @@ from .costant import ROOT_PATH, SITE_NAME, SERIES_FOLDER
video_source = VideoSource() video_source = VideoSource()
table_show_manager = TVShowManager() table_show_manager = TVShowManager()
# download_video
def donwload_video(tv_name: str, index_season_selected: int, index_episode_selected: int) -> None: def download_video(tv_name: str, index_season_selected: int, index_episode_selected: int) -> None:
""" """
Download a single episode video. Download a single episode video.
@ -57,14 +57,14 @@ def donwload_video(tv_name: str, index_season_selected: int, index_episode_selec
).start() ).start()
def donwload_episode(tv_name: str, index_season_selected: int, donwload_all: bool = False) -> None: def download_episode(tv_name: str, index_season_selected: int, download_all: bool = False) -> None:
""" """
Download all episodes of a season. Download all episodes of a season.
Parameters: Parameters:
- tv_name (str): Name of the TV series. - tv_name (str): Name of the TV series.
- index_season_selected (int): Index of the selected season. - index_season_selected (int): Index of the selected season.
- donwload_all (bool): Donwload all seasons episodes - download_all (bool): Download all seasons episodes
""" """
# Clean memory of all episodes and get the number of the season (some dont follow rule of [1,2,3,4,5] but [1,2,3,145,5,6,7]). # Clean memory of all episodes and get the number of the season (some dont follow rule of [1,2,3,4,5] but [1,2,3,145,5,6,7]).
@ -77,14 +77,14 @@ def donwload_episode(tv_name: str, index_season_selected: int, donwload_all: boo
episodes_count = video_source.obj_episode_manager.get_length() episodes_count = video_source.obj_episode_manager.get_length()
# Download all episodes wihtout ask # Download all episodes wihtout ask
if donwload_all: if download_all:
for i_episode in range(1, episodes_count+1): for i_episode in range(1, episodes_count+1):
donwload_video(tv_name, index_season_selected, i_episode) download_video(tv_name, index_season_selected, i_episode)
console.print(f"\n[red]Download [yellow]season: [red]{index_season_selected}.") console.print(f"\n[red]Download [yellow]season: [red]{index_season_selected}.")
# If not download all episode but a single season # If not download all episode but a single season
if not donwload_all: if not download_all:
# Display episodes list and manage user selection # Display episodes list and manage user selection
last_command = display_episodes_list() last_command = display_episodes_list()
@ -92,12 +92,12 @@ def donwload_episode(tv_name: str, index_season_selected: int, donwload_all: boo
# Download selected episodes # Download selected episodes
if len(list_episode_select) == 1 and last_command != "*": if len(list_episode_select) == 1 and last_command != "*":
donwload_video(tv_name, index_season_selected, list_episode_select[0]) download_video(tv_name, index_season_selected, list_episode_select[0])
# Download all other episodes selecter # Download all other episodes selecter
else: else:
for i_episode in list_episode_select: for i_episode in list_episode_select:
donwload_video(tv_name, index_season_selected, i_episode) download_video(tv_name, index_season_selected, i_episode)
def download_series(select_title: MediaItem, domain: str, version: str) -> None: def download_series(select_title: MediaItem, domain: str, version: str) -> None:
@ -121,23 +121,23 @@ def download_series(select_title: MediaItem, domain: str, version: str) -> None:
# Prompt user for season selection and download episodes # Prompt user for season selection and download episodes
console.print(f"\n[green]Season find: [red]{seasons_count}") console.print(f"\n[green]Season find: [red]{seasons_count}")
index_season_selected = str(msg.ask("\n[cyan]Insert media [red]index [yellow]or [red](*) [cyan]to download all media [yellow]or [red][1-2] [cyan]for a range of media")) index_season_selected = msg.ask("\n[cyan]Insert media [red]index [yellow]or [red](*) [cyan]to download all media [yellow]or [red][1-2] [cyan]or [red][3-*] [cyan]for a range of media")
list_season_select = manage_selection(index_season_selected, seasons_count) list_season_select = manage_selection(index_season_selected, seasons_count)
# Download selected episodes # Download selected episodes
if len(list_season_select) == 1 and index_season_selected != "*": if len(list_season_select) == 1 and index_season_selected != "*":
if 1 <= int(index_season_selected) <= seasons_count: if 1 <= int(index_season_selected) <= seasons_count:
donwload_episode(select_title.slug, list_season_select[0]) download_episode(select_title.slug, list_season_select[0])
# Dowload all seasons and episodes # Dowload all seasons and episodes
elif index_season_selected == "*": elif index_season_selected == "*":
for i_season in list_season_select: for i_season in list_season_select:
donwload_episode(select_title.slug, i_season, True) download_episode(select_title.slug, i_season, True)
# Download all other season selecter # Download all other season selecter
else: else:
for i_season in list_season_select: for i_season in list_season_select:
donwload_episode(select_title.slug, i_season) download_episode(select_title.slug, i_season)
def display_episodes_list() -> str: def display_episodes_list() -> str:

View File

@ -6,7 +6,7 @@ from Src.Util.console import console, msg
# Logic class # Logic class
from .site import title_search, run_get_select_title from .site import title_search, run_get_select_title
from .serie import donwload_serie from .serie import download_serie
@ -30,7 +30,7 @@ def search():
select_title = run_get_select_title() select_title = run_get_select_title()
# Download only TV # Download only TV
donwload_serie(select_title) download_serie(select_title)
else: else:
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}") console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")

View File

@ -26,7 +26,7 @@ from .costant import ROOT_PATH, SITE_NAME, SERIES_FOLDER
table_show_manager = TVShowManager() table_show_manager = TVShowManager()
def donwload_video(api_manager: ApiManager, index_season_selected: int, index_episode_selected: int) -> None: def download_video(api_manager: ApiManager, index_season_selected: int, index_episode_selected: int) -> None:
""" """
Download a single episode video. Download a single episode video.
@ -71,14 +71,14 @@ def donwload_video(api_manager: ApiManager, index_season_selected: int, index_ep
) )
def donwload_episode(api_manager: ApiManager, index_season_selected: int, donwload_all: bool = False) -> None: def download_episode(api_manager: ApiManager, index_season_selected: int, download_all: bool = False) -> None:
""" """
Download all episodes of a season. Download all episodes of a season.
Parameters: Parameters:
- tv_name (str): Name of the TV series. - tv_name (str): Name of the TV series.
- index_season_selected (int): Index of the selected season. - index_season_selected (int): Index of the selected season.
- donwload_all (bool): Donwload all seasons episodes - download_all (bool): Download all seasons episodes
""" """
# Clean memory of all episodes and get the number of the season (some dont follow rule of [1,2,3,4,5] but [1,2,3,145,5,6,7]). # Clean memory of all episodes and get the number of the season (some dont follow rule of [1,2,3,4,5] but [1,2,3,145,5,6,7]).
@ -93,14 +93,14 @@ def donwload_episode(api_manager: ApiManager, index_season_selected: int, donwlo
start_message() start_message()
# Download all episodes wihtout ask # Download all episodes wihtout ask
if donwload_all: if download_all:
for i_episode in range(1, episodes_count+1): for i_episode in range(1, episodes_count+1):
donwload_video(api_manager, index_season_selected, i_episode) download_video(api_manager, index_season_selected, i_episode)
console.print(f"\n[red]Download [yellow]season: [red]{index_season_selected}.") console.print(f"\n[red]Download [yellow]season: [red]{index_season_selected}.")
# If not download all episode but a single season # If not download all episode but a single season
if not donwload_all: if not download_all:
# Display episodes list and manage user selection # Display episodes list and manage user selection
last_command = display_episodes_list(api_manager) last_command = display_episodes_list(api_manager)
@ -108,15 +108,15 @@ def donwload_episode(api_manager: ApiManager, index_season_selected: int, donwlo
# Download selected episodes # Download selected episodes
if len(list_episode_select) == 1 and last_command != "*": if len(list_episode_select) == 1 and last_command != "*":
donwload_video(api_manager, index_season_selected, list_episode_select[0]) download_video(api_manager, index_season_selected, list_episode_select[0])
# Download all other episodes selecter # Download all other episodes selecter
else: else:
for i_episode in list_episode_select: for i_episode in list_episode_select:
donwload_video(api_manager, index_season_selected, i_episode) download_video(api_manager, index_season_selected, i_episode)
def donwload_serie(media: MediaItem): def download_serie(media: MediaItem):
""" """
Downloads a media title using its API manager and WebAutomation driver. Downloads a media title using its API manager and WebAutomation driver.
@ -135,23 +135,23 @@ def donwload_serie(media: MediaItem):
# Prompt user for season selection and download episodes # Prompt user for season selection and download episodes
console.print(f"\n[green]Season find: [red]{seasons_count}") console.print(f"\n[green]Season find: [red]{seasons_count}")
index_season_selected = str(msg.ask("\n[cyan]Insert media [red]index [yellow]or [red](*) [cyan]to download all media [yellow]or [red][1-2] [cyan]for a range of media")) index_season_selected = msg.ask("\n[cyan]Insert media [red]index [yellow]or [red](*) [cyan]to download all media [yellow]or [red][1-2] [cyan]or [red][3-*] [cyan]for a range of media")
list_season_select = manage_selection(index_season_selected, seasons_count) list_season_select = manage_selection(index_season_selected, seasons_count)
# Download selected episodes # Download selected episodes
if len(list_season_select) == 1 and index_season_selected != "*": if len(list_season_select) == 1 and index_season_selected != "*":
if 1 <= int(index_season_selected) <= seasons_count: if 1 <= int(index_season_selected) <= seasons_count:
donwload_episode(api_manager, list_season_select[0]) download_episode(api_manager, list_season_select[0])
# Dowload all seasons and episodes # Dowload all seasons and episodes
elif index_season_selected == "*": elif index_season_selected == "*":
for i_season in list_season_select: for i_season in list_season_select:
donwload_episode(api_manager, i_season, True) download_episode(api_manager, i_season, True)
# Download all other season selecter # Download all other season selecter
else: else:
for i_season in list_season_select: for i_season in list_season_select:
donwload_episode(api_manager, i_season) download_episode(api_manager, i_season)
def display_episodes_list(api_manager: ApiManager) -> str: def display_episodes_list(api_manager: ApiManager) -> str:

View File

@ -12,7 +12,6 @@ from unidecode import unidecode
# Internal utilities # Internal utilities
from Src.Util.headers import get_headers
from Src.Util._jsonConfig import config_manager from Src.Util._jsonConfig import config_manager
from Src.Util.console import console, Panel from Src.Util.console import console, Panel
from Src.Util.color import Colors from Src.Util.color import Colors
@ -116,7 +115,7 @@ class HLS_Downloader():
os.makedirs(self.audio_segments_path, exist_ok=True) os.makedirs(self.audio_segments_path, exist_ok=True)
os.makedirs(self.subtitle_segments_path, exist_ok=True) os.makedirs(self.subtitle_segments_path, exist_ok=True)
# Track subtitle, audio donwload # Track subtitle, audio download
self.downloaded_audio = [] self.downloaded_audio = []
self.downloaded_subtitle = [] self.downloaded_subtitle = []
self.downloaded_video = [] self.downloaded_video = []
@ -235,12 +234,15 @@ class HLS_Downloader():
if self.codec is not None: if self.codec is not None:
console.print(f"[cyan]Codec [white]=> ([green]'v'[white]: [yellow]{self.codec.video_codec_name}[white] ([green]b[white]: [yellow]{self.codec.video_bitrate // 1000}k[white]), [green]'a'[white]: [yellow]{self.codec.audio_codec_name}[white] ([green]b[white]: [yellow]{self.codec.audio_bitrate // 1000}k[white]))") console.print(f"[cyan]Codec [white]=> ([green]'v'[white]: [yellow]{self.codec.video_codec_name}[white] ([green]b[white]: [yellow]{self.codec.video_bitrate // 1000}k[white]), [green]'a'[white]: [yellow]{self.codec.audio_codec_name}[white] ([green]b[white]: [yellow]{self.codec.audio_bitrate // 1000}k[white]))")
def __donwload_video__(self): def download_video(self, server_ip: list = None):
""" """
Downloads and manages video segments. Downloads and manages video segments.
This method downloads video segments if necessary and updates This method downloads video segments if necessary and updates
the list of downloaded video segments. the list of downloaded video segments.
Args:
- server_ip (list): A list of IP addresses to use in requests.
""" """
# Construct full path for the video segment directory # Construct full path for the video segment directory
@ -258,6 +260,7 @@ class HLS_Downloader():
if self.is_index_url: if self.is_index_url:
logging.info("Parse index by url.") logging.info("Parse index by url.")
video_m3u8 = M3U8_Segments(self.m3u8_index, full_path_video, True) video_m3u8 = M3U8_Segments(self.m3u8_index, full_path_video, True)
video_m3u8.add_server_ip(server_ip)
else: else:
logging.info("Parse index by text input.") logging.info("Parse index by text input.")
@ -279,12 +282,15 @@ class HLS_Downloader():
else: else:
console.log("[cyan]Video [red]already exists.") console.log("[cyan]Video [red]already exists.")
def __donwload_audio__(self): def download_audio(self, server_ip: list = None):
""" """
Downloads and manages audio segments. Downloads and manages audio segments.
This method iterates over available audio tracks, downloads them if necessary, and updates This method iterates over available audio tracks, downloads them if necessary, and updates
the list of downloaded audio tracks. the list of downloaded audio tracks.
Args:
- server_ip (list): A list of IP addresses to use in requests.
""" """
# Iterate over each available audio track # Iterate over each available audio track
@ -311,6 +317,7 @@ class HLS_Downloader():
# If the audio segment directory doesn't exist, download audio segments # If the audio segment directory doesn't exist, download audio segments
audio_m3u8 = M3U8_Segments(obj_audio.get('uri'), full_path_audio) audio_m3u8 = M3U8_Segments(obj_audio.get('uri'), full_path_audio)
audio_m3u8.add_server_ip(server_ip)
# Get information about the audio segments # Get information about the audio segments
audio_m3u8.get_info() audio_m3u8.get_info()
@ -540,9 +547,12 @@ class HLS_Downloader():
else: else:
logging.info("Video file converted already exist.") logging.info("Video file converted already exist.")
def start(self) -> None: def start(self, server_ip: list = None):
""" """
Start the process of fetching, downloading, joining, and cleaning up the video. Start the process of fetching, downloading, joining, and cleaning up the video.
Args:
- server_ip (list): A list of IP addresses to use in requests.
""" """
# Check if file already exist # Check if file already exist
@ -581,9 +591,9 @@ class HLS_Downloader():
# Start all download ... # Start all download ...
if DOWNLOAD_VIDEO: if DOWNLOAD_VIDEO:
self.__donwload_video__() self.download_video(server_ip)
if DOWNLOAD_AUDIO: if DOWNLOAD_AUDIO:
self.__donwload_audio__() self.download_audio(server_ip)
if DOWNLOAD_SUBTITLE: if DOWNLOAD_SUBTITLE:
self.__download_subtitle__() self.__download_subtitle__()
@ -673,7 +683,7 @@ class HLS_Downloader():
self.m3u8_url_fixer.set_playlist(self.m3u8_index) self.m3u8_url_fixer.set_playlist(self.m3u8_index)
# Start all download ... # Start all download ...
self.__donwload_video__() self.download_video()
# Convert video # Convert video
converted_out_path = self.__join_video__() converted_out_path = self.__join_video__()

View File

@ -8,7 +8,7 @@ import logging
import binascii import binascii
import threading import threading
from queue import PriorityQueue from queue import PriorityQueue
from urllib.parse import urljoin, urlparse from urllib.parse import urljoin, urlparse, urlunparse
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
@ -85,6 +85,20 @@ class M3U8_Segments:
self.queue = PriorityQueue() self.queue = PriorityQueue()
self.stop_event = threading.Event() self.stop_event = threading.Event()
# Server ip
self.fake_proxy = False
def add_server_ip(self, list_ip: list):
"""
Add server IP addresses
Args:
list_ip (list): A list of IP addresses to be added.
"""
if list_ip is not None:
self.fake_proxy = True
self.fake_proxy_ip = list_ip
def __get_key__(self, m3u8_parser: M3U8_Parser) -> bytes: def __get_key__(self, m3u8_parser: M3U8_Parser) -> bytes:
""" """
Retrieves the encryption key from the M3U8 playlist. Retrieves the encryption key from the M3U8 playlist.
@ -118,6 +132,24 @@ class M3U8_Segments:
logging.info(f"Key: ('hex': {hex_content}, 'byte': {byte_content})") logging.info(f"Key: ('hex': {hex_content}, 'byte': {byte_content})")
return byte_content return byte_content
def __gen_proxy__(self, url: str, url_index: int) -> str:
"""
Change the IP address of the provided URL based on the given index.
Args:
- url (str): The original URL that needs its IP address replaced.
- url_index (int): The index used to select a new IP address from the list of FAKE_PROXY_IP.
Returns:
str: The modified URL with the new IP address.
"""
new_ip_address = self.fake_proxy_ip[url_index % len(self.fake_proxy_ip)]
# Parse the original URL and replace the hostname with the new IP address
parsed_url = urlparse(url)._replace(netloc=new_ip_address)
return urlunparse(parsed_url)
def parse_data(self, m3u8_content: str) -> None: def parse_data(self, m3u8_content: str) -> None:
""" """
Parses the M3U8 content to extract segment information. Parses the M3U8 content to extract segment information.
@ -160,7 +192,7 @@ class M3U8_Segments:
# Update segments for estimator # Update segments for estimator
self.class_ts_estimator.total_segments = len(self.segments) self.class_ts_estimator.total_segments = len(self.segments)
logging.info(f"Segmnets to donwload: [{len(self.segments)}]") logging.info(f"Segmnets to download: [{len(self.segments)}]")
# Proxy # Proxy
if THERE_IS_PROXY_LIST: if THERE_IS_PROXY_LIST:
@ -171,6 +203,12 @@ class M3U8_Segments:
if len(self.valid_proxy) == 0: if len(self.valid_proxy) == 0:
sys.exit(0) sys.exit(0)
# Server ip
if self.fake_proxy:
for i in range(len(self.segments)):
segment_url = self.segments[i]
self.segments[i] = self.__gen_proxy__(segment_url, self.segments.index(segment_url))
def get_info(self) -> None: def get_info(self) -> None:
""" """
Makes a request to the index M3U8 file to get information about segments. Makes a request to the index M3U8 file to get information about segments.
@ -205,6 +243,12 @@ class M3U8_Segments:
- index (int): The index of the segment. - index (int): The index of the segment.
- progress_bar (tqdm): Progress counter for tracking download progress. - progress_bar (tqdm): Progress counter for tracking download progress.
""" """
need_verify = REQUEST_VERIFY
# Set to false for only fake proxy that use real ip of server
if self.fake_proxy:
need_verify = False
try: try:
start_time = time.time() start_time = time.time()
@ -215,14 +259,14 @@ class M3U8_Segments:
proxy = self.valid_proxy[index % len(self.valid_proxy)] proxy = self.valid_proxy[index % len(self.valid_proxy)]
logging.info(f"Use proxy: {proxy}") logging.info(f"Use proxy: {proxy}")
with httpx.Client(proxies=proxy, verify=True) as client: with httpx.Client(proxies=proxy, verify=need_verify) as client:
if 'key_base_url' in self.__dict__: if 'key_base_url' in self.__dict__:
response = client.get(ts_url, headers=random_headers(self.key_base_url), timeout=REQUEST_TIMEOUT, follow_redirects=True) response = client.get(ts_url, headers=random_headers(self.key_base_url), timeout=REQUEST_TIMEOUT, follow_redirects=True)
else: else:
response = client.get(ts_url, headers={'user-agent': get_headers()}, timeout=REQUEST_TIMEOUT, follow_redirects=True) response = client.get(ts_url, headers={'user-agent': get_headers()}, timeout=REQUEST_TIMEOUT, follow_redirects=True)
else: else:
with httpx.Client(verify=True) as client_2: with httpx.Client(verify=need_verify) as client_2:
if 'key_base_url' in self.__dict__: if 'key_base_url' in self.__dict__:
response = client_2.get(ts_url, headers=random_headers(self.key_base_url), timeout=REQUEST_TIMEOUT, follow_redirects=True) response = client_2.get(ts_url, headers=random_headers(self.key_base_url), timeout=REQUEST_TIMEOUT, follow_redirects=True)
else: else:

View File

@ -407,7 +407,7 @@ class M3U8_Subtitle:
}) })
except Exception as e: except Exception as e:
logging.error(f"Cant donwload: {obj_subtitle.get('name')}, error: {e}") logging.error(f"Cant download: {obj_subtitle.get('name')}, error: {e}")
return output return output

View File

@ -105,7 +105,8 @@ class TVShowManager:
self.console.print(f"\n\n[yellow][INFO] [green]Press [red]Enter [green]to restart, or [red]'q' [green]to quit.") self.console.print(f"\n\n[yellow][INFO] [green]Press [red]Enter [green]to restart, or [red]'q' [green]to quit.")
if not force_int_input: if not force_int_input:
key = Prompt.ask("[cyan]Insert media [red]index [yellow]or [red](*) [cyan]to download all media [yellow]or [red][1-2] [cyan]for a range of media") key = Prompt.ask("\n[cyan]Insert media [red]index [yellow]or [red](*) [cyan]to download all media [yellow]or [red][1-2] [cyan]or [red][3-*] [cyan]for a range of media")
else: else:
choices = [str(i) for i in range(0, max_int_input)] choices = [str(i) for i in range(0, max_int_input)]
choices.extend(["q", ""]) choices.extend(["q", ""])
@ -128,7 +129,8 @@ class TVShowManager:
else: else:
self.console.print(f"\n\n[yellow][INFO] [red]You've reached the end. [green]Press [red]Enter [green]to restart, or [red]'q' [green]to quit.") self.console.print(f"\n\n[yellow][INFO] [red]You've reached the end. [green]Press [red]Enter [green]to restart, or [red]'q' [green]to quit.")
if not force_int_input: if not force_int_input:
key = Prompt.ask("[cyan]Insert media [red]index [yellow]or [red](*) [cyan]to download all media [yellow]or [red][1-2] [cyan]for a range of media") key = Prompt.ask("\n[cyan]Insert media [red]index [yellow]or [red](*) [cyan]to download all media [yellow]or [red][1-2] [cyan]or [red][3-*] [cyan]for a range of media")
else: else:
choices = [str(i) for i in range(0, max_int_input)] choices = [str(i) for i in range(0, max_int_input)]
choices.extend(["q", ""]) choices.extend(["q", ""])

2
run.py
View File

@ -125,7 +125,7 @@ def initialize():
# Attempting GitHub update # Attempting GitHub update
try: try:
#git_update() git_update()
print() print()
except: except:
console.log("[red]Error with loading github.") console.log("[red]Error with loading github.")