diff --git a/Src/Api/Guardaserie/Core/Class/ScrapeSerie.py b/Src/Api/Guardaserie/Core/Class/ScrapeSerie.py index 0b723b7..3efee8a 100644 --- a/Src/Api/Guardaserie/Core/Class/ScrapeSerie.py +++ b/Src/Api/Guardaserie/Core/Class/ScrapeSerie.py @@ -3,6 +3,8 @@ import sys import logging +from typing import List, Dict + # External libraries import httpx @@ -20,56 +22,93 @@ from .SearchType import MediaItem class GetSerieInfo: - def __init__(self, dict_serie: MediaItem = None) -> None: + def __init__(self, dict_serie: MediaItem) -> None: """ - Initializes the VideoSource object with default values. + Initializes the GetSerieInfo object with default values. - Attributes: - headers (dict): An empty dictionary to store HTTP headers. + Args: + dict_serie (MediaItem): Dictionary containing series information (optional). """ self.headers = {'user-agent': get_headers()} self.url = dict_serie.url self.tv_name = None self.list_episodes = None + self.list_episodes = None - def get_seasons_number(self): + def get_seasons_number(self) -> int: + """ + Retrieves the number of seasons of a TV series. - response = httpx.get(self.url, headers=self.headers) + Returns: + int: Number of seasons of the TV series. + """ + try: - # Create soup and find table - soup = BeautifulSoup(response.text, "html.parser") - table_content = soup.find('div', class_="tt_season") + # Make an HTTP request to the series URL + response = httpx.get(self.url, headers=self.headers) + response.raise_for_status() - seasons_number = len(table_content.find_all("li")) - self.tv_name = soup.find("h1", class_= "front_title").get_text(strip=True) + # Parse HTML content of the page + soup = BeautifulSoup(response.text, "html.parser") + + # Find the container of seasons + table_content = soup.find('div', class_="tt_season") + + # Count the number of seasons + seasons_number = len(table_content.find_all("li")) + + # Extract the name of the series + self.tv_name = soup.find("h1", class_="front_title").get_text(strip=True) + + return seasons_number + + except Exception as e: + logging.error(f"Error parsing HTML page: {e}") + + return -999 + + def get_episode_number(self, n_season: int) -> List[Dict[str, str]]: + """ + Retrieves the number of episodes for a specific season. + + Args: + n_season (int): The season number. + + Returns: + List[Dict[str, str]]: List of dictionaries containing episode information. + """ + try: + + # Make an HTTP request to the series URL + response = httpx.get(self.url, headers=self.headers) + response.raise_for_status() + + # Parse HTML content of the page + soup = BeautifulSoup(response.text, "html.parser") + + # Find the container of episodes for the specified season + table_content = soup.find('div', class_="tab-pane", id=f"season-{n_season}") + + # Extract episode information + episode_content = table_content.find_all("li") + list_dict_episode = [] + + for episode_div in episode_content: + index = episode_div.find("a").get("data-num") + link = episode_div.find("a").get("data-link") + name = episode_div.find("a").get("data-title") + + obj_episode = { + 'number': index, + 'name': name, + 'url': link + } + list_dict_episode.append(obj_episode) + + self.list_episodes = list_dict_episode + return list_dict_episode - return seasons_number - - def get_episode_number(self, n_season: int): + except Exception as e: + logging.error(f"Error parsing HTML page: {e}") - response = httpx.get(self.url, headers=self.headers) - - # Create soup and find table - soup = BeautifulSoup(response.text, "html.parser") - table_content = soup.find('div', class_="tab-pane", id=f"season-{n_season}") - - # Scrape info episode - episode_content = table_content.find_all("li") - list_dict_episode = [] - - for episode_div in episode_content: - - index = episode_div.find("a").get("data-num") - link = episode_div.find("a").get("data-link") - name = episode_div.find("a").get("data-title") - - obj_episode = { - 'number': index, - 'name': name, - 'url': link - } - - list_dict_episode.append(obj_episode) - - self.list_episodes = list_dict_episode - return list_dict_episode \ No newline at end of file + return [] diff --git a/Src/Api/Guardaserie/Core/Player/supervideo.py b/Src/Api/Guardaserie/Core/Player/supervideo.py index 0d1cc04..e97e856 100644 --- a/Src/Api/Guardaserie/Core/Player/supervideo.py +++ b/Src/Api/Guardaserie/Core/Player/supervideo.py @@ -120,4 +120,4 @@ class VideoSource: except Exception as e: logging.error(f"An error occurred: {e}") return None - + \ No newline at end of file diff --git a/Src/Api/Guardaserie/Core/Util/manage_ep.py b/Src/Api/Guardaserie/Core/Util/manage_ep.py index db41275..06b24fd 100644 --- a/Src/Api/Guardaserie/Core/Util/manage_ep.py +++ b/Src/Api/Guardaserie/Core/Util/manage_ep.py @@ -7,6 +7,7 @@ from typing import List # Internal utilities from Src.Util._jsonConfig import config_manager +from Src.Util.os import remove_special_characters # Config @@ -44,4 +45,27 @@ def manage_selection(cmd_insert: str, max_count: int) -> List[int]: logging.info(f"List return: {list_season_select}") return list_season_select +def map_episode_title(tv_name: str, number_season: int, episode_number: int, episode_name: str) -> str: + """ + Maps the episode title to a specific format. + Args: + tv_name (str): The name of the TV show. + number_season (int): The season number. + episode_number (int): The episode number. + episode_name (str): The original name of the episode. + + Returns: + str: The mapped episode title. + """ + map_episode_temp = MAP_EPISODE + map_episode_temp = map_episode_temp.replace("%(tv_name)", remove_special_characters(tv_name)) + map_episode_temp = map_episode_temp.replace("%(season)", str(number_season)) + map_episode_temp = map_episode_temp.replace("%(episode)", str(episode_number)) + map_episode_temp = map_episode_temp.replace("%(episode_name)", remove_special_characters(episode_name)) + + # Additional fix + map_episode_temp = map_episode_temp.replace(".", "_") + + logging.info(f"Map episode string return: {map_episode_temp}") + return map_episode_temp diff --git a/Src/Api/Guardaserie/series.py b/Src/Api/Guardaserie/series.py index c550df9..25e29b0 100644 --- a/Src/Api/Guardaserie/series.py +++ b/Src/Api/Guardaserie/series.py @@ -16,7 +16,7 @@ from Src.Lib.Hls.downloader import Downloader # Logic class from .Core.Class.SearchType import MediaItem from .Core.Class.ScrapeSerie import GetSerieInfo -from .Core.Util.manage_ep import manage_selection +from .Core.Util.manage_ep import manage_selection, map_episode_title from .Core.Player.supervideo import VideoSource @@ -48,7 +48,7 @@ def donwload_video(scape_info_serie: GetSerieInfo, index_season_selected: int, i print() # Define filename and path for the downloaded video - mp4_name = f"{obj_episode.get('name')}.mp4" + mp4_name = f"{map_episode_title(scape_info_serie.tv_name, index_season_selected, index_episode_selected, obj_episode.get('name'))}.mp4" mp4_path = os.path.join(ROOT_PATH, MAIN_FOLDER, SERIES_FOLDER, scape_info_serie.tv_name, f"S{index_season_selected}") # Setup video source diff --git a/Src/Api/Streamingcommunity/Core/Util/manage_ep.py b/Src/Api/Streamingcommunity/Core/Util/manage_ep.py index 331771c..ab4ae71 100644 --- a/Src/Api/Streamingcommunity/Core/Util/manage_ep.py +++ b/Src/Api/Streamingcommunity/Core/Util/manage_ep.py @@ -7,6 +7,7 @@ from typing import List # Internal utilities from Src.Util._jsonConfig import config_manager +from Src.Util.os import remove_special_characters # Logic class @@ -62,10 +63,10 @@ def map_episode_title(tv_name: str, episode: Episode, number_season: int): str: The mapped episode title. """ map_episode_temp = MAP_EPISODE - map_episode_temp = map_episode_temp.replace("%(tv_name)", tv_name) + map_episode_temp = map_episode_temp.replace("%(tv_name)", remove_special_characters(tv_name)) map_episode_temp = map_episode_temp.replace("%(season)", str(number_season).zfill(2)) map_episode_temp = map_episode_temp.replace("%(episode)", str(episode.number).zfill(2)) - map_episode_temp = map_episode_temp.replace("%(episode_name)", episode.name) + map_episode_temp = map_episode_temp.replace("%(episode_name)", remove_special_characters(episode.name)) # Additional fix map_episode_temp = map_episode_temp.replace(".", "_") diff --git a/Src/Api/Streamingcommunity/series.py b/Src/Api/Streamingcommunity/series.py index 96f6c98..460a7ea 100644 --- a/Src/Api/Streamingcommunity/series.py +++ b/Src/Api/Streamingcommunity/series.py @@ -28,44 +28,6 @@ video_source = VideoSource() table_show_manager = TVShowManager() - -def display_episodes_list() -> str: - """ - Display episodes list and handle user input. - - Returns: - last_command (str): Last command entered by the user. - """ - - # Set up table for displaying episodes - table_show_manager.set_slice_end(10) - - # Add columns to the table - column_info = { - "Index": {'color': 'red'}, - "Name": {'color': 'magenta'}, - "Duration": {'color': 'green'} - } - table_show_manager.add_column(column_info) - - # Populate the table with episodes information - for i, media in enumerate(video_source.obj_episode_manager.episodes): - table_show_manager.add_tv_show({ - 'Index': str(media.number), - 'Name': media.name, - 'Duration': str(media.duration) - }) - - # Run the table and handle user input - last_command = table_show_manager.run() - - if last_command == "q": - console.print("\n[red]Quit [white]...") - sys.exit(0) - - return last_command - - def donwload_video(tv_name: str, index_season_selected: int, index_episode_selected: int) -> None: """ Download a single episode video. @@ -187,3 +149,40 @@ def download_series(tv_id: str, tv_name: str, version: str, domain: str) -> None else: for i_season in list_season_select: donwload_episode(tv_name, i_season) + + +def display_episodes_list() -> str: + """ + Display episodes list and handle user input. + + Returns: + last_command (str): Last command entered by the user. + """ + + # Set up table for displaying episodes + table_show_manager.set_slice_end(10) + + # Add columns to the table + column_info = { + "Index": {'color': 'red'}, + "Name": {'color': 'magenta'}, + "Duration": {'color': 'green'} + } + table_show_manager.add_column(column_info) + + # Populate the table with episodes information + for i, media in enumerate(video_source.obj_episode_manager.episodes): + table_show_manager.add_tv_show({ + 'Index': str(media.number), + 'Name': media.name, + 'Duration': str(media.duration) + }) + + # Run the table and handle user input + last_command = table_show_manager.run() + + if last_command == "q": + console.print("\n[red]Quit [white]...") + sys.exit(0) + + return last_command