diff --git a/README.md b/README.md index c7a8914..9629e1f 100644 --- a/README.md +++ b/README.md @@ -214,12 +214,14 @@ The configuration file is divided into several main sections: "movie_folder_name": "Movie", "serie_folder_name": "TV", "map_episode_name": "%(tv_name)_S%(season)E%(episode)_%(episode_name)", + "add_siteName": false, + "disable_searchDomain": false, "not_close": false } ``` - `root_path`: Directory where all videos will be saved - + ### Path examples: * Windows: `C:\\MyLibrary\\Folder` or `\\\\MyServer\\MyLibrary` (if you want to use a network folder) * Linux/MacOS: `Desktop/MyLibrary/Folder` @@ -241,7 +243,10 @@ The configuration file is divided into several main sections: * `%(episode_name)` : Is the name of the episode `

` -- `not_close`: If true, continues running after downloading +- `add_siteName`: If set to true, appends the site_name to the root path before the movie and serie folders. +- `disable_searchDomain`: If set to true, disables the search for a new domain for all sites. +- `not_close`: If set to true, keeps the program running after the download is complete. + ### qBittorrent Configuration @@ -258,7 +263,6 @@ The configuration file is divided into several main sections: To enable qBittorrent integration, follow the setup guide [here](https://github.com/lgallard/qBittorrent-Controller/wiki/How-to-enable-the-qBittorrent-Web-UI). -
## REQUESTS Settings @@ -272,7 +276,6 @@ The configuration file is divided into several main sections: - `timeout`: Maximum timeout (in seconds) for each request - `max_retry`: Number of retry attempts per segment during M3U8 index download -
## M3U8_DOWNLOAD Settings @@ -293,10 +296,9 @@ The configuration file is divided into several main sections: - `cleanup_tmp_folder`: Remove temporary .ts files after download > [!IMPORTANT] -> Set `tqdm_use_large_bar` to `false` when using Termux or terminals with limited width to prevent display issues +> Set `tqdm_use_large_bar` to `false` when using Termux or terminals with limited width to prevent network monitoring issues -
### Language Settings @@ -345,7 +347,6 @@ forced-ita hin - Hindi pol - Polish tur - Turkish - `force_resolution`: Force specific resolution (-1 for best available, or specify 1080, 720, 360) - `get_only_link`: Return M3U8 playlist/index URL instead of downloading -
# COMMAND @@ -361,7 +362,6 @@ forced-ita hin - Hindi pol - Polish tur - Turkish - Enter a season number followed by `-*` to download from that season to the end. * **Example:** `3-*` will download from *Season 3* to the final season. -
# Docker diff --git a/StreamingCommunity/Api/Player/Helper/Vixcloud/util.py b/StreamingCommunity/Api/Player/Helper/Vixcloud/util.py index ee6a563..5912955 100644 --- a/StreamingCommunity/Api/Player/Helper/Vixcloud/util.py +++ b/StreamingCommunity/Api/Player/Helper/Vixcloud/util.py @@ -5,20 +5,14 @@ from typing import Dict, Any, List, Union class Episode: def __init__(self, data: Dict[str, Any]): - self.images = None self.data = data - self.id: int = data.get('id') - self.scws_id: int = data.get('scws_id') - self.number: int = data.get('number') - self.name: str = data.get('name') - self.plot: str = data.get('plot') - self.duration: int = data.get('duration') - - def collect_image(self, SITE_NAME, domain): - self.image = None - if len(self.data.get('images')) > 0: - self.image = f"https://cdn.{SITE_NAME}.{domain}/images/{self.data.get('images')[0]['filename']}" + self.id: int = data.get('id', 0) + self.scws_id: int = data.get('scws_id', 0) + self.number: int = data.get('number', 1) + self.name: str = data.get('name', '') + self.plot: str = data.get('plot', '') + self.duration: int = data.get('duration', 0) def __str__(self): return f"Episode(id={self.id}, number={self.number}, name='{self.name}', plot='{self.plot}', duration={self.duration} sec)" @@ -73,24 +67,19 @@ class EpisodeManager: class Season: def __init__(self, season_data: Dict[str, Union[int, str, None]]): - self.images = {} self.season_data = season_data - self.id: int = season_data.get('id') - self.scws_id: int = season_data.get('scws_id') - self.imdb_id: int = season_data.get('imdb_id') - self.number: int = season_data.get('number') - self.name: str = season_data.get('name') - self.slug: str = season_data.get('slug') - self.plot: str = season_data.get('plot') - self.type: str = season_data.get('type') - self.seasons_count: int = season_data.get('seasons_count') + self.id: int = season_data.get('id', 0) + self.scws_id: int = season_data.get('scws_id', 0) + self.imdb_id: int = season_data.get('imdb_id', 0) + self.number: int = season_data.get('number', 0) + self.name: str = season_data.get('name', '') + self.slug: str = season_data.get('slug', '') + self.plot: str = season_data.get('plot', '') + self.type: str = season_data.get('type', '') + self.seasons_count: int = season_data.get('seasons_count', 0) self.episodes: EpisodeManager = EpisodeManager() - def collect_images(self, SITE_NAME, domain): - for dict_image in self.season_data.get('images'): - self.images[dict_image.get('type')] = f"https://cdn.{SITE_NAME}.{domain}/images/{dict_image.get('filename')}" - class Stream: def __init__(self, name: str, url: str, active: bool): diff --git a/StreamingCommunity/Api/Site/1337xx/site.py b/StreamingCommunity/Api/Site/1337xx/site.py index 69192f8..6b9a54c 100644 --- a/StreamingCommunity/Api/Site/1337xx/site.py +++ b/StreamingCommunity/Api/Site/1337xx/site.py @@ -19,9 +19,11 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaManager # Variable -from .costant import SITE_NAME +from .costant import SITE_NAME, DOMAIN_NOW media_search_manager = MediaManager() table_show_manager = TVShowManager() +max_timeout = config_manager.get_int("REQUESTS", "timeout") +disable_searchDomain = config_manager.get_bool("DEFAULT", "disable_searchDomain") def title_search(word_to_search: str) -> int: @@ -38,8 +40,10 @@ def title_search(word_to_search: str) -> int: table_show_manager.clear() # Find new domain if prev dont work - max_timeout = config_manager.get_int("REQUESTS", "timeout") - domain_to_use, _ = search_domain(SITE_NAME, f"https://{SITE_NAME}") + domain_to_use = DOMAIN_NOW + + if not disable_searchDomain: + domain_to_use, base_url = search_domain(SITE_NAME, f"https://{SITE_NAME}") # Construct the full site URL and load the search page try: diff --git a/StreamingCommunity/Api/Site/1337xx/title.py b/StreamingCommunity/Api/Site/1337xx/title.py index ea84933..bdf9b9e 100644 --- a/StreamingCommunity/Api/Site/1337xx/title.py +++ b/StreamingCommunity/Api/Site/1337xx/title.py @@ -21,7 +21,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem # Config -from .costant import ROOT_PATH, DOMAIN_NOW, SITE_NAME, MOVIE_FOLDER +from .costant import DOMAIN_NOW, SITE_NAME, MOVIE_FOLDER def download_title(select_title: MediaItem): @@ -39,7 +39,7 @@ def download_title(select_title: MediaItem): # Define output path title_name = os_manager.get_sanitize_file(select_title.name) mp4_path = os_manager.get_sanitize_path( - os.path.join(ROOT_PATH, MOVIE_FOLDER, title_name.replace(".mp4", "")) + os.path.join(MOVIE_FOLDER, title_name.replace(".mp4", "")) ) # Create output folder diff --git a/StreamingCommunity/Api/Site/altadefinizione/costant.py b/StreamingCommunity/Api/Site/altadefinizione/costant.py index 5bac8f6..cb76a8b 100644 --- a/StreamingCommunity/Api/Site/altadefinizione/costant.py +++ b/StreamingCommunity/Api/Site/altadefinizione/costant.py @@ -11,5 +11,9 @@ SITE_NAME = os.path.basename(os.path.dirname(os.path.abspath(__file__))) ROOT_PATH = config_manager.get('DEFAULT', 'root_path') DOMAIN_NOW = config_manager.get_dict('SITE', SITE_NAME)['domain'] -SERIES_FOLDER = config_manager.get('DEFAULT', 'serie_folder_name') -MOVIE_FOLDER = config_manager.get('DEFAULT', 'movie_folder_name') \ No newline at end of file +SERIES_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'serie_folder_name')) +MOVIE_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'movie_folder_name')) + +if config_manager.get_bool("DEFAULT", "add_siteName"): + SERIES_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'serie_folder_name')) + MOVIE_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'movie_folder_name')) \ No newline at end of file diff --git a/StreamingCommunity/Api/Site/altadefinizione/film.py b/StreamingCommunity/Api/Site/altadefinizione/film.py index 2c38a34..204d98d 100644 --- a/StreamingCommunity/Api/Site/altadefinizione/film.py +++ b/StreamingCommunity/Api/Site/altadefinizione/film.py @@ -22,7 +22,7 @@ from StreamingCommunity.Api.Player.supervideo import VideoSource # Config -from .costant import ROOT_PATH, MOVIE_FOLDER +from .costant import MOVIE_FOLDER def download_film(select_title: MediaItem) -> str: @@ -47,7 +47,7 @@ def download_film(select_title: MediaItem) -> str: # Define output path title_name = os_manager.get_sanitize_file(select_title.name) + ".mp4" mp4_path = os_manager.get_sanitize_path( - os.path.join(ROOT_PATH, MOVIE_FOLDER, title_name.replace(".mp4", "")) + os.path.join(MOVIE_FOLDER, title_name.replace(".mp4", "")) ) # Get m3u8 master playlist diff --git a/StreamingCommunity/Api/Site/altadefinizione/site.py b/StreamingCommunity/Api/Site/altadefinizione/site.py index 5f47b00..3045fde 100644 --- a/StreamingCommunity/Api/Site/altadefinizione/site.py +++ b/StreamingCommunity/Api/Site/altadefinizione/site.py @@ -19,9 +19,11 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaManager # Variable -from .costant import SITE_NAME +from .costant import SITE_NAME, DOMAIN_NOW media_search_manager = MediaManager() table_show_manager = TVShowManager() +max_timeout = config_manager.get_int("REQUESTS", "timeout") +disable_searchDomain = config_manager.get_bool("DEFAULT", "disable_searchDomain") def title_search(title_search: str) -> int: @@ -38,9 +40,11 @@ def title_search(title_search: str) -> int: table_show_manager.clear() # Find new domain if prev dont work - max_timeout = config_manager.get_int("REQUESTS", "timeout") - domain_to_use, _ = search_domain(SITE_NAME, f"https://{SITE_NAME}") + domain_to_use = DOMAIN_NOW + if not disable_searchDomain: + domain_to_use, base_url = search_domain(SITE_NAME, f"https://{SITE_NAME}") + # Send request to search for title client = httpx.Client() diff --git a/StreamingCommunity/Api/Site/animeunity/costant.py b/StreamingCommunity/Api/Site/animeunity/costant.py index 5bac8f6..cb76a8b 100644 --- a/StreamingCommunity/Api/Site/animeunity/costant.py +++ b/StreamingCommunity/Api/Site/animeunity/costant.py @@ -11,5 +11,9 @@ SITE_NAME = os.path.basename(os.path.dirname(os.path.abspath(__file__))) ROOT_PATH = config_manager.get('DEFAULT', 'root_path') DOMAIN_NOW = config_manager.get_dict('SITE', SITE_NAME)['domain'] -SERIES_FOLDER = config_manager.get('DEFAULT', 'serie_folder_name') -MOVIE_FOLDER = config_manager.get('DEFAULT', 'movie_folder_name') \ No newline at end of file +SERIES_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'serie_folder_name')) +MOVIE_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'movie_folder_name')) + +if config_manager.get_bool("DEFAULT", "add_siteName"): + SERIES_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'serie_folder_name')) + MOVIE_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'movie_folder_name')) \ No newline at end of file diff --git a/StreamingCommunity/Api/Site/animeunity/film_serie.py b/StreamingCommunity/Api/Site/animeunity/film_serie.py index a6ddab4..ae62255 100644 --- a/StreamingCommunity/Api/Site/animeunity/film_serie.py +++ b/StreamingCommunity/Api/Site/animeunity/film_serie.py @@ -23,7 +23,7 @@ from StreamingCommunity.Api.Player.vixcloud import VideoSourceAnime # Variable -from .costant import ROOT_PATH, SITE_NAME, SERIES_FOLDER, MOVIE_FOLDER +from .costant import SITE_NAME, SERIES_FOLDER, MOVIE_FOLDER @@ -54,11 +54,11 @@ def download_episode(index_select: int, scrape_serie: ScrapeSerieAnime, video_so if scrape_serie.is_series: mp4_path = os_manager.get_sanitize_path( - os.path.join(ROOT_PATH, SERIES_FOLDER, scrape_serie.series_name) + os.path.join(SERIES_FOLDER, scrape_serie.series_name) ) else: mp4_path = os_manager.get_sanitize_path( - os.path.join(ROOT_PATH, MOVIE_FOLDER, scrape_serie.series_name) + os.path.join(MOVIE_FOLDER, scrape_serie.series_name) ) # Create output folder diff --git a/StreamingCommunity/Api/Site/animeunity/site.py b/StreamingCommunity/Api/Site/animeunity/site.py index f37a20f..0e6d949 100644 --- a/StreamingCommunity/Api/Site/animeunity/site.py +++ b/StreamingCommunity/Api/Site/animeunity/site.py @@ -21,10 +21,11 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaManager # Variable -from .costant import SITE_NAME +from .costant import SITE_NAME, DOMAIN_NOW media_search_manager = MediaManager() table_show_manager = TVShowManager() - +max_timeout = config_manager.get_int("REQUESTS", "timeout") +disable_searchDomain = config_manager.get_bool("DEFAULT", "disable_searchDomain") def get_token(site_name: str, domain: str) -> dict: @@ -40,7 +41,10 @@ def get_token(site_name: str, domain: str) -> dict: """ # Send a GET request to the specified URL composed of the site name and domain - response = httpx.get(f"https://www.{site_name}.{domain}") + response = httpx.get( + url=f"https://www.{site_name}.{domain}", + timeout=max_timeout + ) response.raise_for_status() # Initialize variables to store CSRF token @@ -103,8 +107,10 @@ def title_search(title: str) -> int: table_show_manager.clear() # Get token and session value from configuration - max_timeout = config_manager.get_int("REQUESTS", "timeout") - domain_to_use, _ = search_domain(SITE_NAME, f"https://www.{SITE_NAME}") + domain_to_use = DOMAIN_NOW + + if not disable_searchDomain: + domain_to_use, base_url = search_domain(SITE_NAME, f"https://www.{SITE_NAME}") data = get_token(SITE_NAME, domain_to_use) diff --git a/StreamingCommunity/Api/Site/cb01new/costant.py b/StreamingCommunity/Api/Site/cb01new/costant.py index 6edd9ae..72d34e9 100644 --- a/StreamingCommunity/Api/Site/cb01new/costant.py +++ b/StreamingCommunity/Api/Site/cb01new/costant.py @@ -11,5 +11,9 @@ SITE_NAME = os.path.basename(os.path.dirname(os.path.abspath(__file__))) ROOT_PATH = config_manager.get('DEFAULT', 'root_path') DOMAIN_NOW = config_manager.get_dict('SITE', SITE_NAME)['domain'] -SERIES_FOLDER = config_manager.get('DEFAULT', 'serie_folder_name') -MOVIE_FOLDER = config_manager.get('DEFAULT', 'movie_folder_name') +SERIES_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'serie_folder_name')) +MOVIE_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'movie_folder_name')) + +if config_manager.get_bool("DEFAULT", "add_siteName"): + SERIES_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'serie_folder_name')) + MOVIE_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'movie_folder_name')) diff --git a/StreamingCommunity/Api/Site/cb01new/film.py b/StreamingCommunity/Api/Site/cb01new/film.py index 7603582..11a1304 100644 --- a/StreamingCommunity/Api/Site/cb01new/film.py +++ b/StreamingCommunity/Api/Site/cb01new/film.py @@ -21,7 +21,7 @@ from StreamingCommunity.Api.Player.maxstream import VideoSource # Config -from .costant import ROOT_PATH, MOVIE_FOLDER +from .costant import MOVIE_FOLDER def download_film(select_title: MediaItem) -> str: @@ -46,7 +46,7 @@ def download_film(select_title: MediaItem) -> str: # Define output path title_name = os_manager.get_sanitize_file(select_title.name) +".mp4" mp4_path = os_manager.get_sanitize_path( - os.path.join(ROOT_PATH, MOVIE_FOLDER, title_name.replace(".mp4", "")) + os.path.join(MOVIE_FOLDER, title_name.replace(".mp4", "")) ) # Get m3u8 master playlist diff --git a/StreamingCommunity/Api/Site/cb01new/site.py b/StreamingCommunity/Api/Site/cb01new/site.py index 559e232..20f7173 100644 --- a/StreamingCommunity/Api/Site/cb01new/site.py +++ b/StreamingCommunity/Api/Site/cb01new/site.py @@ -18,9 +18,11 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaManager # Variable -from .costant import SITE_NAME +from .costant import SITE_NAME, DOMAIN_NOW media_search_manager = MediaManager() table_show_manager = TVShowManager() +max_timeout = config_manager.get_int("REQUESTS", "timeout") +disable_searchDomain = config_manager.get_bool("DEFAULT", "disable_searchDomain") def title_search(word_to_search: str) -> int: @@ -37,8 +39,10 @@ def title_search(word_to_search: str) -> int: table_show_manager.clear() # Find new domain if prev dont work - max_timeout = config_manager.get_int("REQUESTS", "timeout") - domain_to_use, _ = search_domain(SITE_NAME, f"https://{SITE_NAME}") + domain_to_use = DOMAIN_NOW + + if not disable_searchDomain: + domain_to_use, base_url = search_domain(SITE_NAME, f"https://{SITE_NAME}") response = httpx.get( url=f"https://{SITE_NAME}.{domain_to_use}/?s={word_to_search}", diff --git a/StreamingCommunity/Api/Site/ddlstreamitaly/costant.py b/StreamingCommunity/Api/Site/ddlstreamitaly/costant.py index 858bfd8..576ad37 100644 --- a/StreamingCommunity/Api/Site/ddlstreamitaly/costant.py +++ b/StreamingCommunity/Api/Site/ddlstreamitaly/costant.py @@ -12,5 +12,9 @@ ROOT_PATH = config_manager.get('DEFAULT', 'root_path') DOMAIN_NOW = config_manager.get_dict('SITE', SITE_NAME)['domain'] COOKIE = config_manager.get_dict('SITE', SITE_NAME)['extra'] -SERIES_FOLDER = config_manager.get('DEFAULT', 'serie_folder_name') -MOVIE_FOLDER = config_manager.get('DEFAULT', 'movie_folder_name') +SERIES_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'serie_folder_name')) +MOVIE_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'movie_folder_name')) + +if config_manager.get_bool("DEFAULT", "add_siteName"): + SERIES_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'serie_folder_name')) + MOVIE_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'movie_folder_name')) diff --git a/StreamingCommunity/Api/Site/ddlstreamitaly/series.py b/StreamingCommunity/Api/Site/ddlstreamitaly/series.py index a91c720..95a4078 100644 --- a/StreamingCommunity/Api/Site/ddlstreamitaly/series.py +++ b/StreamingCommunity/Api/Site/ddlstreamitaly/series.py @@ -24,7 +24,7 @@ from StreamingCommunity.Api.Player.ddl import VideoSource # Variable -from .costant import ROOT_PATH, SERIES_FOLDER +from .costant import SERIES_FOLDER @@ -51,7 +51,7 @@ def download_video(index_episode_selected: int, scape_info_serie: GetSerieInfo, title_name = os_manager.get_sanitize_file( f"{map_episode_title(scape_info_serie.tv_name, None, index_episode_selected, obj_episode.get('name'))}.mp4" ) - mp4_path = os.path.join(ROOT_PATH, SERIES_FOLDER, scape_info_serie.tv_name) + mp4_path = os.path.join(SERIES_FOLDER, scape_info_serie.tv_name) # Create output folder os_manager.create_path(mp4_path) diff --git a/StreamingCommunity/Api/Site/ddlstreamitaly/site.py b/StreamingCommunity/Api/Site/ddlstreamitaly/site.py index aa429aa..ab46b72 100644 --- a/StreamingCommunity/Api/Site/ddlstreamitaly/site.py +++ b/StreamingCommunity/Api/Site/ddlstreamitaly/site.py @@ -22,9 +22,11 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaManager # Variable -from .costant import SITE_NAME +from .costant import SITE_NAME, DOMAIN_NOW media_search_manager = MediaManager() table_show_manager = TVShowManager() +max_timeout = config_manager.get_int("REQUESTS", "timeout") +disable_searchDomain = config_manager.get_bool("DEFAULT", "disable_searchDomain") def title_search(word_to_search: str) -> int: @@ -41,8 +43,10 @@ def title_search(word_to_search: str) -> int: table_show_manager.clear() # Find new domain if prev dont work - max_timeout = config_manager.get_int("REQUESTS", "timeout") - domain_to_use, _ = search_domain(SITE_NAME, f"https://{SITE_NAME}") + domain_to_use = DOMAIN_NOW + + if not disable_searchDomain: + domain_to_use, base_url = search_domain(SITE_NAME, f"https://{SITE_NAME}") # Send request to search for titles try: diff --git a/StreamingCommunity/Api/Site/guardaserie/costant.py b/StreamingCommunity/Api/Site/guardaserie/costant.py index c7012aa..9ce5286 100644 --- a/StreamingCommunity/Api/Site/guardaserie/costant.py +++ b/StreamingCommunity/Api/Site/guardaserie/costant.py @@ -11,5 +11,9 @@ SITE_NAME = os.path.basename(os.path.dirname(os.path.abspath(__file__))) ROOT_PATH = config_manager.get('DEFAULT', 'root_path') DOMAIN_NOW = config_manager.get_dict('SITE', SITE_NAME)['domain'] -SERIES_FOLDER = config_manager.get('DEFAULT', 'serie_folder_name') -MOVIE_FOLDER = config_manager.get('DEFAULT', 'movie_folder_name') +SERIES_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'serie_folder_name')) +MOVIE_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'movie_folder_name')) + +if config_manager.get_bool("DEFAULT", "add_siteName"): + SERIES_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'serie_folder_name')) + MOVIE_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'movie_folder_name')) diff --git a/StreamingCommunity/Api/Site/guardaserie/series.py b/StreamingCommunity/Api/Site/guardaserie/series.py index 5f5ebd8..cd8ef67 100644 --- a/StreamingCommunity/Api/Site/guardaserie/series.py +++ b/StreamingCommunity/Api/Site/guardaserie/series.py @@ -2,7 +2,6 @@ import os import sys -import time # Internal utilities @@ -24,7 +23,7 @@ from StreamingCommunity.Api.Player.supervideo import VideoSource # Variable -from .costant import ROOT_PATH, SERIES_FOLDER +from .costant import SERIES_FOLDER @@ -50,7 +49,7 @@ def download_video(index_season_selected: int, index_episode_selected: int, scap # Define filename and path for the downloaded video 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, SERIES_FOLDER, scape_info_serie.tv_name, f"S{index_season_selected}") + mp4_path = os.path.join(SERIES_FOLDER, scape_info_serie.tv_name, f"S{index_season_selected}") # Setup video source video_source = VideoSource(obj_episode.get('url')) diff --git a/StreamingCommunity/Api/Site/guardaserie/site.py b/StreamingCommunity/Api/Site/guardaserie/site.py index e1a12f7..25e9eae 100644 --- a/StreamingCommunity/Api/Site/guardaserie/site.py +++ b/StreamingCommunity/Api/Site/guardaserie/site.py @@ -19,9 +19,11 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaManager # Variable -from .costant import SITE_NAME +from .costant import SITE_NAME, DOMAIN_NOW media_search_manager = MediaManager() table_show_manager = TVShowManager() +max_timeout = config_manager.get_int("REQUESTS", "timeout") +disable_searchDomain = config_manager.get_bool("DEFAULT", "disable_searchDomain") def title_search(word_to_search: str) -> int: @@ -38,8 +40,10 @@ def title_search(word_to_search: str) -> int: table_show_manager.clear() # Find new domain if prev dont work - max_timeout = config_manager.get_int("REQUESTS", "timeout") - domain_to_use, _ = search_domain(SITE_NAME, f"https://{SITE_NAME}") + domain_to_use = DOMAIN_NOW + + if not disable_searchDomain: + domain_to_use, base_url = search_domain(SITE_NAME, f"https://{SITE_NAME}") # Send request to search for titles try: diff --git a/StreamingCommunity/Api/Site/ilcorsaronero/costant.py b/StreamingCommunity/Api/Site/ilcorsaronero/costant.py index c4bd929..fefb15d 100644 --- a/StreamingCommunity/Api/Site/ilcorsaronero/costant.py +++ b/StreamingCommunity/Api/Site/ilcorsaronero/costant.py @@ -11,5 +11,9 @@ SITE_NAME = os.path.basename(os.path.dirname(os.path.abspath(__file__))) ROOT_PATH = config_manager.get('DEFAULT', 'root_path') DOMAIN_NOW = config_manager.get_dict('SITE', SITE_NAME)['domain'] -SERIES_FOLDER = config_manager.get('DEFAULT', 'serie_folder_name') -MOVIE_FOLDER = config_manager.get('DEFAULT', 'movie_folder_name') \ No newline at end of file +SERIES_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'serie_folder_name')) +MOVIE_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'movie_folder_name')) + +if config_manager.get_bool("DEFAULT", "add_siteName"): + SERIES_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'serie_folder_name')) + MOVIE_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'movie_folder_name')) \ No newline at end of file diff --git a/StreamingCommunity/Api/Site/ilcorsaronero/site.py b/StreamingCommunity/Api/Site/ilcorsaronero/site.py index a9458c6..14df4c0 100644 --- a/StreamingCommunity/Api/Site/ilcorsaronero/site.py +++ b/StreamingCommunity/Api/Site/ilcorsaronero/site.py @@ -2,6 +2,7 @@ # Internal utilities +from StreamingCommunity.Util._jsonConfig import config_manager from StreamingCommunity.Util.table import TVShowManager @@ -13,9 +14,11 @@ from .util.ilCorsarScraper import IlCorsaroNeroScraper # Variable -from .costant import SITE_NAME +from .costant import SITE_NAME, DOMAIN_NOW media_search_manager = MediaManager() table_show_manager = TVShowManager() +max_timeout = config_manager.get_int("REQUESTS", "timeout") +disable_searchDomain = config_manager.get_bool("DEFAULT", "disable_searchDomain") async def title_search(word_to_search: str) -> int: @@ -32,7 +35,10 @@ async def title_search(word_to_search: str) -> int: table_show_manager.clear() # Find new domain if prev dont work - domain_to_use, _ = search_domain(SITE_NAME, f"https://{SITE_NAME}") + domain_to_use = DOMAIN_NOW + + if not disable_searchDomain: + domain_to_use, base_url = search_domain(SITE_NAME, f"https://{SITE_NAME}") # Create scraper and collect result print("\n") diff --git a/StreamingCommunity/Api/Site/ilcorsaronero/title.py b/StreamingCommunity/Api/Site/ilcorsaronero/title.py index 322e5fa..886de89 100644 --- a/StreamingCommunity/Api/Site/ilcorsaronero/title.py +++ b/StreamingCommunity/Api/Site/ilcorsaronero/title.py @@ -15,7 +15,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem # Config -from .costant import ROOT_PATH, MOVIE_FOLDER +from .costant import MOVIE_FOLDER def download_title(select_title: MediaItem): @@ -27,13 +27,13 @@ def download_title(select_title: MediaItem): """ start_message() - console.print(f"[yellow]Download: [red]{select_title.name} \n") + console.print(f"[yellow]Download: [red]{select_title.name} \n") print() # Define output path title_name = os_manager.get_sanitize_file(select_title.name) mp4_path = os_manager.get_sanitize_path( - os.path.join(ROOT_PATH, MOVIE_FOLDER, title_name.replace(".mp4", "")) + os.path.join(MOVIE_FOLDER, title_name.replace(".mp4", "")) ) # Create output folder diff --git a/StreamingCommunity/Api/Site/mostraguarda/costant.py b/StreamingCommunity/Api/Site/mostraguarda/costant.py index 5bac8f6..cb76a8b 100644 --- a/StreamingCommunity/Api/Site/mostraguarda/costant.py +++ b/StreamingCommunity/Api/Site/mostraguarda/costant.py @@ -11,5 +11,9 @@ SITE_NAME = os.path.basename(os.path.dirname(os.path.abspath(__file__))) ROOT_PATH = config_manager.get('DEFAULT', 'root_path') DOMAIN_NOW = config_manager.get_dict('SITE', SITE_NAME)['domain'] -SERIES_FOLDER = config_manager.get('DEFAULT', 'serie_folder_name') -MOVIE_FOLDER = config_manager.get('DEFAULT', 'movie_folder_name') \ No newline at end of file +SERIES_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'serie_folder_name')) +MOVIE_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'movie_folder_name')) + +if config_manager.get_bool("DEFAULT", "add_siteName"): + SERIES_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'serie_folder_name')) + MOVIE_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'movie_folder_name')) \ No newline at end of file diff --git a/StreamingCommunity/Api/Site/mostraguarda/film.py b/StreamingCommunity/Api/Site/mostraguarda/film.py index 642cc73..b7889d9 100644 --- a/StreamingCommunity/Api/Site/mostraguarda/film.py +++ b/StreamingCommunity/Api/Site/mostraguarda/film.py @@ -33,7 +33,7 @@ from StreamingCommunity.Lib.TMBD import Json_film # Config -from .costant import ROOT_PATH, SITE_NAME, DOMAIN_NOW, MOVIE_FOLDER +from .costant import SITE_NAME, DOMAIN_NOW, MOVIE_FOLDER def download_film(movie_details: Json_film) -> str: @@ -75,7 +75,7 @@ def download_film(movie_details: Json_film) -> str: # Define output path title_name = os_manager.get_sanitize_file(movie_details.title) + ".mp4" - mp4_path = os.path.join(ROOT_PATH, MOVIE_FOLDER, title_name.replace(".mp4", "")) + mp4_path = os.path.join(MOVIE_FOLDER, title_name.replace(".mp4", "")) # Get m3u8 master playlist master_playlist = video_source.get_playlist() diff --git a/StreamingCommunity/Api/Site/streamingcommunity/costant.py b/StreamingCommunity/Api/Site/streamingcommunity/costant.py index bdd0d0d..cb76a8b 100644 --- a/StreamingCommunity/Api/Site/streamingcommunity/costant.py +++ b/StreamingCommunity/Api/Site/streamingcommunity/costant.py @@ -9,7 +9,11 @@ from StreamingCommunity.Util._jsonConfig import config_manager SITE_NAME = os.path.basename(os.path.dirname(os.path.abspath(__file__))) ROOT_PATH = config_manager.get('DEFAULT', 'root_path') -DOMAIN_NOW = config_manager.get('SITE', SITE_NAME) +DOMAIN_NOW = config_manager.get_dict('SITE', SITE_NAME)['domain'] -SERIES_FOLDER = config_manager.get('DEFAULT', 'serie_folder_name') -MOVIE_FOLDER = config_manager.get('DEFAULT', 'movie_folder_name') \ No newline at end of file +SERIES_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'serie_folder_name')) +MOVIE_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'movie_folder_name')) + +if config_manager.get_bool("DEFAULT", "add_siteName"): + SERIES_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'serie_folder_name')) + MOVIE_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'movie_folder_name')) \ No newline at end of file diff --git a/StreamingCommunity/Api/Site/streamingcommunity/film.py b/StreamingCommunity/Api/Site/streamingcommunity/film.py index 2f1fe05..b176ddd 100644 --- a/StreamingCommunity/Api/Site/streamingcommunity/film.py +++ b/StreamingCommunity/Api/Site/streamingcommunity/film.py @@ -22,7 +22,7 @@ from StreamingCommunity.Api.Player.vixcloud import VideoSource # Variable -from .costant import ROOT_PATH, SITE_NAME, MOVIE_FOLDER +from .costant import SITE_NAME, MOVIE_FOLDER def download_film(select_title: MediaItem) -> str: @@ -51,8 +51,8 @@ def download_film(select_title: MediaItem) -> str: master_playlist = video_source.get_playlist() # Define the filename and path for the downloaded film - title_name = os_manager.get_sanitize_file(select_title.slug) + ".mp4" - mp4_path = os.path.join(ROOT_PATH, MOVIE_FOLDER, select_title.slug) + title_name = os_manager.get_sanitize_file(select_title.name) + ".mp4" + mp4_path = os.path.join(MOVIE_FOLDER, select_title.name) # Download the film using the m3u8 playlist, and output filename r_proc = HLS_Downloader( diff --git a/StreamingCommunity/Api/Site/streamingcommunity/series.py b/StreamingCommunity/Api/Site/streamingcommunity/series.py index 12b97d9..11755de 100644 --- a/StreamingCommunity/Api/Site/streamingcommunity/series.py +++ b/StreamingCommunity/Api/Site/streamingcommunity/series.py @@ -24,7 +24,7 @@ from StreamingCommunity.Api.Player.vixcloud import VideoSource # Variable -from .costant import ROOT_PATH, SITE_NAME, SERIES_FOLDER +from .costant import SITE_NAME, SERIES_FOLDER @@ -48,7 +48,7 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra # Define filename and path for the downloaded video mp4_name = f"{map_episode_title(scrape_serie.series_name, index_season_selected, index_episode_selected, obj_episode.name)}.mp4" - mp4_path = os.path.join(ROOT_PATH, SERIES_FOLDER, scrape_serie.series_name, f"S{index_season_selected}") + mp4_path = os.path.join(SERIES_FOLDER, scrape_serie.series_name, f"S{index_season_selected}") # Retrieve scws and if available master playlist video_source.get_iframe(obj_episode.id) diff --git a/StreamingCommunity/Api/Site/streamingcommunity/site.py b/StreamingCommunity/Api/Site/streamingcommunity/site.py index 3a9b4af..c85ac69 100644 --- a/StreamingCommunity/Api/Site/streamingcommunity/site.py +++ b/StreamingCommunity/Api/Site/streamingcommunity/site.py @@ -26,30 +26,36 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaManager # Config -from .costant import SITE_NAME +from .costant import SITE_NAME, DOMAIN_NOW # Variable media_search_manager = MediaManager() table_show_manager = TVShowManager() max_timeout = config_manager.get_int("REQUESTS", "timeout") +disable_searchDomain = config_manager.get_bool("DEFAULT", "disable_searchDomain") -def get_version(text: str): +def get_version(domain: str): """ Extracts the version from the HTML text of a webpage. Parameters: - - text (str): The HTML text of the webpage. + - domain (str): The domain of the site. Returns: str: The version extracted from the webpage. - list: Top 10 titles headlines for today. """ try: + response = httpx.get( + url=f"https://{SITE_NAME}.{domain}/", + headers={'User-Agent': get_headers()}, + timeout=max_timeout + ) + response.raise_for_status() # Parse request to site - soup = BeautifulSoup(text, "html.parser") + soup = BeautifulSoup(response.text, "html.parser") # Extract version version = json.loads(soup.find("div", {"id": "app"}).get("data-page"))['version'] @@ -72,22 +78,13 @@ def get_version_and_domain(): """ # Find new domain if prev dont work - domain_to_use, base_url = search_domain(SITE_NAME, f"https://{SITE_NAME}") + domain_to_use = DOMAIN_NOW - # Extract version from the response - try: - version = get_version( - httpx.get( - url=base_url, - headers={'User-Agent': get_headers()}, - timeout=max_timeout - ).text - ) + if not disable_searchDomain: + domain_to_use, base_url = search_domain(SITE_NAME, f"https://{SITE_NAME}") + + version = get_version(domain_to_use) - except: - console.print("[green]Auto generate version ...") - version = secrets.token_hex(32 // 2) - return version, domain_to_use diff --git a/StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py b/StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py index 3dc2fd5..7c8bd5f 100644 --- a/StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +++ b/StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py @@ -1,10 +1,12 @@ # 01.03.24 +import json import logging # External libraries import httpx +from bs4 import BeautifulSoup # Internal utilities @@ -56,33 +58,33 @@ class ScrapeSerie: Raises: Exception: If there's an error fetching season information """ - self.headers = { - 'user-agent': get_headers(), - 'x-inertia': 'true', - 'x-inertia-version': self.version, - } - try: - response = httpx.get( - url=f"https://{self.base_name}.{self.domain}/titles/{self.media_id}-{self.series_name}", - headers=self.headers, + url=f"https://{self.base_name}.{self.domain}/titles/{self.media_id}-{self.series_name}", + headers=self.headers, timeout=max_timeout ) response.raise_for_status() # Extract seasons from JSON response - json_response = response.json().get('props') + soup = BeautifulSoup(response.text, "html.parser") + json_response = json.loads(soup.find("div", {"id": "app"}).get("data-page")) + + """ + response = httpx.post( + url=f'https://{self.base_name}.{self.domain}/api/titles/preview/{self.media_id}', + headers={'User-Agent': get_headers()} + ) + response.raise_for_status() + + + # Extract seasons from JSON response + json_response = response.json() + """ # Collect info about season - self.season_manager = Season(json_response.get('title')) - self.season_manager.collect_images(self.base_name, self.domain) + self.season_manager = Season(json_response.get("props").get("title")) - # Collect first episode info - for i, ep in enumerate(json_response.get('loadedSeason').get('episodes')): - self.season_manager.episodes.add(ep) - self.season_manager.episodes.get(i).collect_image(self.base_name, self.domain) - except Exception as e: logging.error(f"Error collecting season info: {e}") raise @@ -97,16 +99,14 @@ class ScrapeSerie: Raises: Exception: If there's an error fetching episode information """ - self.headers = { - 'user-agent': get_headers(), - 'x-inertia': 'true', - 'x-inertia-version': self.version, - } - try: response = httpx.get( url=f'https://{self.base_name}.{self.domain}/titles/{self.media_id}-{self.series_name}/stagione-{number_season}', - headers=self.headers, + headers={ + 'User-Agent': get_headers(), + 'x-inertia': 'true', + 'x-inertia-version': self.version, + }, timeout=max_timeout ) response.raise_for_status() diff --git a/StreamingCommunity/Lib/Downloader/HLS/downloader.py b/StreamingCommunity/Lib/Downloader/HLS/downloader.py index c63c22a..279b690 100644 --- a/StreamingCommunity/Lib/Downloader/HLS/downloader.py +++ b/StreamingCommunity/Lib/Downloader/HLS/downloader.py @@ -104,14 +104,15 @@ class HttpClient: response = httpx.get( url=url, headers=self.headers, - timeout=max_timeout + timeout=max_timeout, + follow_redirects=True ) response.raise_for_status() return response.text except Exception as e: - logging.info(f"Request to {url} failed with error: {e}") + console.print(f"Request to {url} failed with error: {e}") return 404 def get_content(self, url): diff --git a/StreamingCommunity/Lib/Downloader/HLS/segments.py b/StreamingCommunity/Lib/Downloader/HLS/segments.py index ed4aab7..4905c7c 100644 --- a/StreamingCommunity/Lib/Downloader/HLS/segments.py +++ b/StreamingCommunity/Lib/Downloader/HLS/segments.py @@ -194,23 +194,28 @@ class M3U8_Segments: """ if self.is_index_url: - # Send a GET request to retrieve the index M3U8 file - response = httpx.get( - self.url, - headers={'User-Agent': get_headers()}, - timeout=max_timeout - ) - response.raise_for_status() + try: - # Save the M3U8 file to the temporary folder - path_m3u8_file = os.path.join(self.tmp_folder, "playlist.m3u8") - open(path_m3u8_file, "w+").write(response.text) + # Send a GET request to retrieve the index M3U8 file + response = httpx.get( + self.url, + headers={'User-Agent': get_headers()}, + timeout=max_timeout, + follow_redirects=True + ) + response.raise_for_status() - # Parse the text from the M3U8 index file - self.parse_data(response.text) + # Save the M3U8 file to the temporary folder + path_m3u8_file = os.path.join(self.tmp_folder, "playlist.m3u8") + open(path_m3u8_file, "w+").write(response.text) + + # Parse the text from the M3U8 index file + self.parse_data(response.text) + + except Exception as e: + print(f"Error during M3U8 index request: {e}") else: - # Parser data of content of index pass in input to class self.parse_data(self.url) @@ -385,7 +390,7 @@ class M3U8_Segments: buffer[index] = segment_content except queue.Empty: - self.current_timeout = min(self.max_timeout, self.current_timeout * 1.5) + self.current_timeout = min(self.max_timeout, self.current_timeout * 1.25) if self.stop_event.is_set(): break @@ -546,7 +551,7 @@ class M3U8_Segments: raise Exception("Output file is empty") # Display additional - if self.info_nRetry >= len(self.segments) * (1/3.33): + if self.info_nRetry >= len(self.segments) * 0.3: # Get expected time ex_hours, ex_minutes, ex_seconds = format_duration(self.expected_real_time_s) diff --git a/StreamingCommunity/Upload/version.py b/StreamingCommunity/Upload/version.py index 4bf15c1..956341d 100644 --- a/StreamingCommunity/Upload/version.py +++ b/StreamingCommunity/Upload/version.py @@ -1,5 +1,5 @@ __title__ = 'StreamingCommunity' -__version__ = '2.2.0' +__version__ = '2.3.0' __author__ = 'Lovi-0' __description__ = 'A command-line program to download film' __copyright__ = 'Copyright 2024' diff --git a/config.json b/config.json index 5894011..95865b8 100644 --- a/config.json +++ b/config.json @@ -15,6 +15,8 @@ "user": "admin", "pass": "adminadmin" }, + "add_siteName": true, + "disable_searchDomain": true, "not_close": false }, "REQUESTS": { @@ -24,7 +26,7 @@ "proxy_start_max": 0.5 }, "M3U8_DOWNLOAD": { - "tqdm_delay": 0.01, + "tqdm_delay": 0.12, "tqdm_use_large_bar": true, "default_video_workser": 12, "default_audio_workser": 12,