mirror of
https://github.com/Arrowar/StreamingCommunity.git
synced 2025-06-07 12:05:35 +00:00
Add options [4-*]
This commit is contained in:
parent
8c1baf929a
commit
49a8826142
@ -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))
|
||||||
|
@ -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}")
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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:
|
||||||
|
@ -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:
|
||||||
|
@ -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}")
|
||||||
|
@ -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:
|
||||||
|
@ -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__()
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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", ""])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user