diff --git a/README.md b/README.md
index 8018fc1..7ff53c4 100644
--- a/README.md
+++ b/README.md
@@ -748,26 +748,24 @@ The `run-container` command mounts also the `config.json` file, so any change to
The bot was created to replace terminal commands and allow interaction via Telegram. Each download runs within a screen session, enabling multiple downloads to run simultaneously.
To run the bot in the background, simply start it inside a screen session and then press Ctrl + A, followed by D, to detach from the session without stopping the bot.
-
-
-
-๐ค Bot Commands
Command Functions:
๐น /start โ Starts a new search for a download. This command performs the same operations as manually running the script in the terminal with test_run.py.
๐น /list โ Displays the status of active downloads, with options to:
-- Stop an incorrect download using /stop
-- View the real-time output of a download using /screen
+
+Stop an incorrect download using /stop .
+
+View the real-time output of a download using /screen .
โ Warning: If a download is interrupted, incomplete files may remain in the folder specified in config.json. These files must be deleted manually to avoid storage or management issues.
-
-
-๐ง Environment Setup
+๐ Configuration: Currently, the bot's settings are stored in the config.json file, which is located in the same directory as the telegram_bot.py script.
-Create an `.env` file with:
+## .env Example:
+
+You need to create an .env file and enter your Telegram token and user ID to authorize only one user to use it
```
TOKEN_TELEGRAM=IlTuo2131TOKEN$12D3Telegram
diff --git a/StreamingCommunity/Api/Player/vixcloud.py b/StreamingCommunity/Api/Player/vixcloud.py
index 0c9d881..ed3c871 100644
--- a/StreamingCommunity/Api/Player/vixcloud.py
+++ b/StreamingCommunity/Api/Player/vixcloud.py
@@ -1,6 +1,6 @@
# 01.03.24
-import sys
+import time
import logging
from urllib.parse import urlparse, parse_qs, urlencode, urlunparse
@@ -24,7 +24,7 @@ console = Console()
class VideoSource:
- def __init__(self, url: str, is_series: bool, media_id: int = None):
+ def __init__(self, url: str, is_series: bool, media_id: int = None, proxy: str = None):
"""
Initialize video source for streaming site.
@@ -35,6 +35,7 @@ class VideoSource:
"""
self.headers = {'user-agent': get_userAgent()}
self.url = url
+ self.proxy = proxy
self.is_series = is_series
self.media_id = media_id
self.iframe_src = None
@@ -55,7 +56,7 @@ class VideoSource:
}
try:
- response = httpx.get(f"{self.url}/iframe/{self.media_id}", params=params, timeout=MAX_TIMEOUT)
+ response = httpx.get(f"{self.url}/iframe/{self.media_id}", headers=self.headers, params=params, timeout=MAX_TIMEOUT, proxy=self.proxy)
response.raise_for_status()
# Parse response with BeautifulSoup to get iframe source
@@ -81,6 +82,7 @@ class VideoSource:
self.window_video = WindowVideo(converter.get('video'))
self.window_streams = StreamsCollection(converter.get('streams'))
self.window_parameter = WindowParameter(converter.get('masterPlaylist'))
+ time.sleep(0.5)
except Exception as e:
logging.error(f"Error parsing script: {e}")
diff --git a/StreamingCommunity/Api/Site/1337xx/__init__.py b/StreamingCommunity/Api/Site/1337xx/__init__.py
index 983a41a..637c639 100644
--- a/StreamingCommunity/Api/Site/1337xx/__init__.py
+++ b/StreamingCommunity/Api/Site/1337xx/__init__.py
@@ -24,7 +24,7 @@ indice = 3
_useFor = "Torrent"
_priority = 0
_engineDownload = "Torrent"
-_deprecate = False
+_deprecate = True
console = Console()
msg = Prompt()
@@ -62,7 +62,7 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
return media_search_manager
if len_database > 0:
- select_title = get_select_title(table_show_manager, media_search_manager)
+ select_title = get_select_title(table_show_manager, media_search_manager, len_database)
download_title(select_title)
else:
diff --git a/StreamingCommunity/Api/Site/altadefinizione/__init__.py b/StreamingCommunity/Api/Site/altadefinizione/__init__.py
index 8e7452a..cdbc08d 100644
--- a/StreamingCommunity/Api/Site/altadefinizione/__init__.py
+++ b/StreamingCommunity/Api/Site/altadefinizione/__init__.py
@@ -110,7 +110,7 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
bot = get_bot_instance()
if len_database > 0:
- select_title = get_select_title(table_show_manager, media_search_manager)
+ select_title = get_select_title(table_show_manager, media_search_manager, len_database)
process_search_result(select_title, selections)
else:
diff --git a/StreamingCommunity/Api/Site/animeunity/__init__.py b/StreamingCommunity/Api/Site/animeunity/__init__.py
index 1dfc7fa..990e9bc 100644
--- a/StreamingCommunity/Api/Site/animeunity/__init__.py
+++ b/StreamingCommunity/Api/Site/animeunity/__init__.py
@@ -109,7 +109,7 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
bot = get_bot_instance()
if len_database > 0:
- select_title = get_select_title(table_show_manager, media_search_manager)
+ select_title = get_select_title(table_show_manager, media_search_manager,len_database)
process_search_result(select_title, selections)
else:
diff --git a/StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py b/StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py
index fd76d1d..218c1f2 100644
--- a/StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py
+++ b/StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py
@@ -43,40 +43,38 @@ class ScrapeSerieAnime:
def get_count_episodes(self):
"""
Retrieve total number of episodes for the selected media.
+ This includes partial episodes (like episode 6.5).
Returns:
- int: Total episode count
+ int: Total episode count including partial episodes
"""
- try:
-
- response = httpx.get(
- url=f"{self.url}/info_api/{self.media_id}/",
- headers=self.headers,
- timeout=max_timeout
- )
- response.raise_for_status()
-
- # Parse JSON response and return episode count
- return response.json()["episodes_count"]
-
- except Exception as e:
- logging.error(f"Error fetching episode count: {e}")
- return None
+ if self.episodes_cache is None:
+ self._fetch_all_episodes()
+
+ if self.episodes_cache:
+ return len(self.episodes_cache)
+ return None
def _fetch_all_episodes(self):
"""
Fetch all episodes data at once and cache it
"""
try:
- all_episodes = []
- count = self.get_count_episodes()
- if not count:
- return
+ # Get initial episode count
+ response = httpx.get(
+ url=f"{self.url}/info_api/{self.media_id}/",
+ headers=self.headers,
+ timeout=max_timeout
+ )
+ response.raise_for_status()
+ initial_count = response.json()["episodes_count"]
- # Fetch episodes
+ all_episodes = []
start_range = 1
- while start_range <= count:
- end_range = min(start_range + 119, count)
+
+ # Fetch episodes in chunks
+ while start_range <= initial_count:
+ end_range = min(start_range + 119, initial_count)
response = httpx.get(
url=f"{self.url}/info_api/{self.media_id}/1",
diff --git a/StreamingCommunity/Api/Site/animeworld/__init__.py b/StreamingCommunity/Api/Site/animeworld/__init__.py
index da58834..530bf0c 100644
--- a/StreamingCommunity/Api/Site/animeworld/__init__.py
+++ b/StreamingCommunity/Api/Site/animeworld/__init__.py
@@ -75,7 +75,7 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
return media_search_manager
if len_database > 0:
- select_title = get_select_title(table_show_manager, media_search_manager)
+ select_title = get_select_title(table_show_manager, media_search_manager,len_database)
process_search_result(select_title, selections)
else:
diff --git a/StreamingCommunity/Api/Site/cb01new/__init__.py b/StreamingCommunity/Api/Site/cb01new/__init__.py
index c48ddc2..5f3f7f8 100644
--- a/StreamingCommunity/Api/Site/cb01new/__init__.py
+++ b/StreamingCommunity/Api/Site/cb01new/__init__.py
@@ -62,7 +62,7 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
return media_search_manager
if len_database > 0:
- select_title = get_select_title(table_show_manager, media_search_manager)
+ select_title = get_select_title(table_show_manager, media_search_manager,len_database)
process_search_result(select_title)
else:
diff --git a/StreamingCommunity/Api/Site/guardaserie/__init__.py b/StreamingCommunity/Api/Site/guardaserie/__init__.py
index 6970ec1..8abf18b 100644
--- a/StreamingCommunity/Api/Site/guardaserie/__init__.py
+++ b/StreamingCommunity/Api/Site/guardaserie/__init__.py
@@ -75,7 +75,7 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
return media_search_manager
if len_database > 0:
- select_title = get_select_title(table_show_manager, media_search_manager)
+ select_title = get_select_title(table_show_manager, media_search_manager,len_database)
process_search_result(select_title, selections)
else:
diff --git a/StreamingCommunity/Api/Site/raiplay/__init__.py b/StreamingCommunity/Api/Site/raiplay/__init__.py
index ace9a0d..d1b7e23 100644
--- a/StreamingCommunity/Api/Site/raiplay/__init__.py
+++ b/StreamingCommunity/Api/Site/raiplay/__init__.py
@@ -84,7 +84,7 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
return media_search_manager
if len_database > 0:
- select_title = get_select_title(table_show_manager, media_search_manager)
+ select_title = get_select_title(table_show_manager, media_search_manager,len_database)
process_search_result(select_title, selections)
else:
diff --git a/StreamingCommunity/Api/Site/streamingcommunity/__init__.py b/StreamingCommunity/Api/Site/streamingcommunity/__init__.py
index ca47530..b6346f8 100644
--- a/StreamingCommunity/Api/Site/streamingcommunity/__init__.py
+++ b/StreamingCommunity/Api/Site/streamingcommunity/__init__.py
@@ -26,48 +26,72 @@ from .series import download_series
# Variable
indice = 0
-_useFor = "Film_&_Serie"
+_useFor = "Film_&_Serie" # "Movies_&_Series"
_priority = 0
_engineDownload = "hls"
_deprecate = False
msg = Prompt()
console = Console()
+proxy = None
def get_user_input(string_to_search: str = None):
"""
Asks the user to input a search term.
Handles both Telegram bot input and direct input.
+ If string_to_search is provided, it's returned directly (after stripping).
"""
- if string_to_search is None:
- if site_constant.TELEGRAM_BOT:
- bot = get_bot_instance()
- string_to_search = bot.ask(
- "key_search",
- f"Enter the search term\nor type 'back' to return to the menu: ",
- None
- )
+ if string_to_search is not None:
+ return string_to_search.strip()
- if string_to_search == 'back':
+ if site_constant.TELEGRAM_BOT:
+ bot = get_bot_instance()
+ user_response = bot.ask(
+ "key_search", # Request type
+ "Enter the search term\nor type 'back' to return to the menu: ",
+ None
+ )
+ if user_response is None:
+ bot.send_message("Timeout: No search term entered.", None)
+ return None
+
+ if user_response.lower() == 'back':
+ bot.send_message("Returning to the main menu...", None)
+
+ try:
# Restart the script
subprocess.Popen([sys.executable] + sys.argv)
sys.exit()
- else:
- string_to_search = msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
-
- return string_to_search
+
+ except Exception as e:
+ bot.send_message(f"Error during restart attempt: {e}", None)
+ return None # Return None if restart fails
+
+ return user_response.strip()
+
+ else:
+ return msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
def process_search_result(select_title, selections=None, proxy=None):
"""
Handles the search result and initiates the download for either a film or series.
Parameters:
- select_title (MediaItem): The selected media item
+ select_title (MediaItem): The selected media item. Can be None if selection fails.
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
- {'season': season_selection, 'episode': episode_selection}
+ e.g., {'season': season_selection, 'episode': episode_selection}
+ proxy (str, optional): The proxy to use for downloads.
"""
+ if not select_title:
+ if site_constant.TELEGRAM_BOT:
+ bot = get_bot_instance()
+ bot.send_message("No title selected or selection cancelled.", None)
+ else:
+ console.print("[yellow]No title selected or selection cancelled.")
+ return
+
if select_title.type == 'tv':
season_selection = None
episode_selection = None
@@ -77,57 +101,64 @@ def process_search_result(select_title, selections=None, proxy=None):
episode_selection = selections.get('episode')
download_series(select_title, season_selection, episode_selection, proxy)
-
+
else:
- download_film(select_title)
+ download_film(select_title, proxy)
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None, selections: dict = None):
"""
Main function of the application for search.
Parameters:
- string_to_search (str, optional): String to search for
- get_onlyDatabase (bool, optional): If True, return only the database object
- direct_item (dict, optional): Direct item to process (bypass search)
+ string_to_search (str, optional): String to search for. Can be passed from run.py.
+ If 'back', special handling might occur in get_user_input.
+ get_onlyDatabase (bool, optional): If True, return only the database search manager object.
+ direct_item (dict, optional): Direct item to process (bypasses search).
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
- {'season': season_selection, 'episode': episode_selection}
+ for series (season/episode).
"""
+ bot = None
+ if site_constant.TELEGRAM_BOT:
+ bot = get_bot_instance()
+
if direct_item:
- select_title = MediaItem(**direct_item)
- process_search_result(select_title, selections)
+ select_title_obj = MediaItem(**direct_item)
+ process_search_result(select_title_obj, selections, proxy)
+ return
+
+ # Check proxy if not already set
+ finder = ProxyFinder(site_constant.FULL_URL)
+ proxy = finder.find_fast_proxy()
+
+ actual_search_query = get_user_input(string_to_search)
+
+ # Handle cases where user input is empty, or 'back' was handled (sys.exit or None return)
+ if not actual_search_query:
+ if bot:
+ if actual_search_query is None: # Specifically for timeout from bot.ask or failed restart
+ bot.send_message("Search term not provided or operation cancelled. Returning.", None)
return
- if string_to_search is None:
- if site_constant.TELEGRAM_BOT:
- bot = get_bot_instance()
- string_to_search = bot.ask(
- "key_search",
- f"Enter the search term\nor type 'back' to return to the menu: ",
- None
- )
-
- if string_to_search == 'back':
-
- # Restart the script
- subprocess.Popen([sys.executable] + sys.argv)
- sys.exit()
- else:
- string_to_search = msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
-
- # Search on database
+ # Perform search on the database using the obtained query
finder = ProxyFinder(site_constant.FULL_URL)
proxy = finder.find_fast_proxy()
len_database = title_search(string_to_search, proxy)
- # If only the database is needed, return the manager
+ # If only the database object (media_search_manager populated by title_search) is needed
if get_onlyDatabase:
- return media_search_manager
+ return media_search_manager
if len_database > 0:
- select_title = get_select_title(table_show_manager, media_search_manager)
+ select_title = get_select_title(table_show_manager, media_search_manager, len_database)
process_search_result(select_title, selections, proxy)
else:
- # If no results are found, ask again
- console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
- search()
\ No newline at end of file
+ no_results_message = f"No results found for: '{actual_search_query}'"
+ if bot:
+ bot.send_message(no_results_message, None)
+ else:
+ console.print(f"\n[red]Nothing matching was found for[white]: [purple]{actual_search_query}")
+
+ # Do not call search() recursively here to avoid infinite loops on no results.
+ # The flow should return to the caller (e.g., main menu in run.py).
+ return
\ No newline at end of file
diff --git a/StreamingCommunity/Api/Site/streamingcommunity/film.py b/StreamingCommunity/Api/Site/streamingcommunity/film.py
index d70b162..6cbe862 100644
--- a/StreamingCommunity/Api/Site/streamingcommunity/film.py
+++ b/StreamingCommunity/Api/Site/streamingcommunity/film.py
@@ -27,7 +27,7 @@ from StreamingCommunity.Api.Player.vixcloud import VideoSource
console = Console()
-def download_film(select_title: MediaItem) -> str:
+def download_film(select_title: MediaItem, proxy: str = None) -> str:
"""
Downloads a film using the provided film ID, title name, and domain.
@@ -55,7 +55,7 @@ def download_film(select_title: MediaItem) -> str:
console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] โ [cyan]{select_title.name}[/cyan] \n")
# Init class
- video_source = VideoSource(f"{site_constant.FULL_URL}/it", False, select_title.id)
+ video_source = VideoSource(f"{site_constant.FULL_URL}/it", False, select_title.id, proxy)
# Retrieve scws and if available master playlist
video_source.get_iframe(select_title.id)
diff --git a/StreamingCommunity/Api/Site/streamingcommunity/series.py b/StreamingCommunity/Api/Site/streamingcommunity/series.py
index 1fde4e1..f75517d 100644
--- a/StreamingCommunity/Api/Site/streamingcommunity/series.py
+++ b/StreamingCommunity/Api/Site/streamingcommunity/series.py
@@ -154,7 +154,7 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
start_message()
# Init class
- video_source = VideoSource(f"{site_constant.FULL_URL}/it", True, select_season.id)
+ video_source = VideoSource(f"{site_constant.FULL_URL}/it", True, select_season.id, proxy)
scrape_serie = GetSerieInfo(f"{site_constant.FULL_URL}/it", select_season.id, select_season.slug, proxy)
# Collect information about season
diff --git a/StreamingCommunity/Api/Site/streamingcommunity/site.py b/StreamingCommunity/Api/Site/streamingcommunity/site.py
index f42631d..2b58043 100644
--- a/StreamingCommunity/Api/Site/streamingcommunity/site.py
+++ b/StreamingCommunity/Api/Site/streamingcommunity/site.py
@@ -120,4 +120,4 @@ def title_search(query: str, proxy: str) -> int:
bot.send_message(f"Lista dei risultati:", choices)
# Return the number of titles found
- return media_search_manager.get_length()
\ No newline at end of file
+ return media_search_manager.get_length()
diff --git a/StreamingCommunity/Api/Site/streamingwatch/__init__.py b/StreamingCommunity/Api/Site/streamingwatch/__init__.py
index fbf7cf4..b8dffd0 100644
--- a/StreamingCommunity/Api/Site/streamingwatch/__init__.py
+++ b/StreamingCommunity/Api/Site/streamingwatch/__init__.py
@@ -27,6 +27,7 @@ _deprecate = False
msg = Prompt()
console = Console()
+proxy = None
def get_user_input(string_to_search: str = None):
@@ -74,10 +75,15 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
select_title = MediaItem(**direct_item)
process_search_result(select_title, selections) # DONT SUPPORT PROXY FOR NOW
return
+
+ # Check proxy if not already set
+ finder = ProxyFinder(site_constant.FULL_URL)
+ proxy = finder.find_fast_proxy()
if string_to_search is None:
string_to_search = msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
+ # Perform search on the database using the obtained query
finder = ProxyFinder(url=f"{site_constant.FULL_URL}/serie/euphoria/")
proxy = finder.find_fast_proxy()
len_database = title_search(string_to_search, proxy)
@@ -87,7 +93,7 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
return media_search_manager
if len_database > 0:
- select_title = get_select_title(table_show_manager, media_search_manager)
+ select_title = get_select_title(table_show_manager, media_search_manager,len_database)
process_search_result(select_title, selections, proxy)
else:
diff --git a/StreamingCommunity/Api/Template/site.py b/StreamingCommunity/Api/Template/site.py
index ac2ef86..8f1d135 100644
--- a/StreamingCommunity/Api/Template/site.py
+++ b/StreamingCommunity/Api/Template/site.py
@@ -7,78 +7,123 @@ import sys
from rich.console import Console
+# Internal utilities
+from StreamingCommunity.Api.Template.config_loader import site_constant
+from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
+
# Variable
console = Console()
available_colors = ['red', 'magenta', 'yellow', 'cyan', 'green', 'blue', 'white']
column_to_hide = ['Slug', 'Sub_ita', 'Last_air_date', 'Seasons_count', 'Url', 'Image', 'Path_id']
-def get_select_title(table_show_manager, media_search_manager):
+def get_select_title(table_show_manager, media_search_manager, num_results_available):
"""
Display a selection of titles and prompt the user to choose one.
+ Handles both console and Telegram bot input.
+
+ Parameters:
+ table_show_manager: Manager for console table display.
+ media_search_manager: Manager holding the list of media items.
+ num_results_available (int): The number of media items available for selection.
Returns:
- MediaItem: The selected media item.
+ MediaItem: The selected media item, or None if no selection is made or an error occurs.
"""
- # Determine column_info dynamically for (search site)
if not media_search_manager.media_list:
- console.print("\n[red]No media items available.")
+
+ # console.print("\n[red]No media items available.")
return None
-
- # Example of available colors for columns
- available_colors = ['red', 'magenta', 'yellow', 'cyan', 'green', 'blue', 'white']
-
- # Retrieve the keys of the first media item as column headers
- first_media_item = media_search_manager.media_list[0]
- column_info = {"Index": {'color': available_colors[0]}} # Always include Index with a fixed color
- # Assign colors to the remaining keys dynamically
- color_index = 1
- for key in first_media_item.__dict__.keys():
+ if site_constant.TELEGRAM_BOT:
+ bot = get_bot_instance()
+ prompt_message = f"Inserisci il numero del titolo che vuoi selezionare (da 0 a {num_results_available - 1}):"
+
+ user_input_str = bot.ask(
+ "select_title_from_list_number",
+ prompt_message,
+ None
+ )
- if key.capitalize() in column_to_hide:
- continue
+ if user_input_str is None:
+ bot.send_message("Timeout: nessuna selezione ricevuta.", None)
+ return None
- if key in ('id', 'type', 'name', 'score'): # Custom prioritization of colors
- if key == 'type':
- column_info["Type"] = {'color': 'yellow'}
- elif key == 'name':
- column_info["Name"] = {'color': 'magenta'}
- elif key == 'score':
- column_info["Score"] = {'color': 'cyan'}
+ try:
+ chosen_index = int(user_input_str)
+ if 0 <= chosen_index < num_results_available:
+ selected_item = media_search_manager.get(chosen_index)
+ if selected_item:
+ return selected_item
+
+ else:
+ bot.send_message(f"Errore interno: Impossibile recuperare il titolo con indice {chosen_index}.", None)
+ return None
+ else:
+ bot.send_message(f"Selezione '{chosen_index}' non valida. Inserisci un numero compreso tra 0 e {num_results_available - 1}.", None)
+ return None
+
+ except ValueError:
+ bot.send_message(f"Input '{user_input_str}' non valido. Devi inserire un numero.", None)
+ return None
+
+ except Exception as e:
+ bot.send_message(f"Si รจ verificato un errore durante la selezione: {e}", None)
+ return None
- else:
- column_info[key.capitalize()] = {'color': available_colors[color_index % len(available_colors)]}
- color_index += 1
-
- table_show_manager.add_column(column_info)
-
- # Populate the table with title information
- for i, media in enumerate(media_search_manager.media_list):
- media_dict = {'Index': str(i)}
+ else:
+
+ # Logica originale per la console
+ if not media_search_manager.media_list:
+ console.print("\n[red]No media items available.")
+ return None
+
+ first_media_item = media_search_manager.media_list[0]
+ column_info = {"Index": {'color': available_colors[0]}}
+ color_index = 1
for key in first_media_item.__dict__.keys():
if key.capitalize() in column_to_hide:
continue
+ if key in ('id', 'type', 'name', 'score'):
+ if key == 'type': column_info["Type"] = {'color': 'yellow'}
+ elif key == 'name': column_info["Name"] = {'color': 'magenta'}
+ elif key == 'score': column_info["Score"] = {'color': 'cyan'}
+ else:
+ column_info[key.capitalize()] = {'color': available_colors[color_index % len(available_colors)]}
+ color_index += 1
- # Ensure all values are strings for rich add table
- media_dict[key.capitalize()] = str(getattr(media, key))
+ table_show_manager.clear()
+ table_show_manager.add_column(column_info)
- table_show_manager.add_tv_show(media_dict)
+ for i, media in enumerate(media_search_manager.media_list):
+ media_dict = {'Index': str(i)}
+ for key in first_media_item.__dict__.keys():
+ if key.capitalize() in column_to_hide:
+ continue
+ media_dict[key.capitalize()] = str(getattr(media, key))
+ table_show_manager.add_tv_show(media_dict)
- # Run the table and handle user input
- last_command = table_show_manager.run(force_int_input=True, max_int_input=len(media_search_manager.media_list))
- table_show_manager.clear()
+ last_command_str = table_show_manager.run(force_int_input=True, max_int_input=len(media_search_manager.media_list))
+ table_show_manager.clear()
- # Handle user's quit command
- if last_command == "q" or last_command == "quit":
- console.print("\n[red]Quit ...")
- sys.exit(0)
+ if last_command_str is None or last_command_str.lower() in ["q", "quit"]:
+ console.print("\n[red]Selezione annullata o uscita.")
+ return None
- # Check if the selected index is within range
- if 0 <= int(last_command) < len(media_search_manager.media_list):
- return media_search_manager.get(int(last_command))
-
- else:
- console.print("\n[red]Wrong index")
- sys.exit(0)
\ No newline at end of file
+ try:
+
+ selected_index = int(last_command_str)
+
+ if 0 <= selected_index < len(media_search_manager.media_list):
+ return media_search_manager.get(selected_index)
+
+ else:
+ console.print("\n[red]Indice errato o non valido.")
+ # sys.exit(0)
+ return None
+
+ except ValueError:
+ console.print("\n[red]Input non numerico ricevuto dalla tabella.")
+ # sys.exit(0)
+ return None
diff --git a/StreamingCommunity/Lib/Proxies/proxy.py b/StreamingCommunity/Lib/Proxies/proxy.py
index 3d03e5b..b42590e 100644
--- a/StreamingCommunity/Lib/Proxies/proxy.py
+++ b/StreamingCommunity/Lib/Proxies/proxy.py
@@ -32,7 +32,7 @@ class ProxyFinder:
proxy, source = proxy_info
try:
start = time.time()
- print(f"[yellow]Testing proxy...")
+ print(f"[yellow]Testing proxy for URL: {self.url}...")
with httpx.Client(proxy=proxy, timeout=self.timeout_threshold) as client:
response = client.get(self.url, headers=get_headers())
diff --git a/StreamingCommunity/TelegramHelp/config.json b/StreamingCommunity/TelegramHelp/config.json
new file mode 100644
index 0000000..7ef4c0f
--- /dev/null
+++ b/StreamingCommunity/TelegramHelp/config.json
@@ -0,0 +1,62 @@
+{
+ "DEFAULT": {
+ "debug": false,
+ "show_message": true,
+ "clean_console": true,
+ "show_trending": true,
+ "use_api": true,
+ "not_close": false,
+ "telegram_bot": true,
+ "download_site_data": true,
+ "validate_github_config": true
+ },
+ "OUT_FOLDER": {
+ "root_path": "/mnt/data/media/",
+ "movie_folder_name": "films",
+ "serie_folder_name": "serie_tv",
+ "anime_folder_name": "Anime",
+ "map_episode_name": "E%(episode)_%(episode_name)",
+ "add_siteName": false
+ },
+ "QBIT_CONFIG": {
+ "host": "192.168.1.51",
+ "port": "6666",
+ "user": "admin",
+ "pass": "adminadmin"
+ },
+ "M3U8_DOWNLOAD": {
+ "tqdm_delay": 0.01,
+ "default_video_workser": 12,
+ "default_audio_workser": 12,
+ "segment_timeout": 8,
+ "download_audio": true,
+ "merge_audio": true,
+ "specific_list_audio": [
+ "ita"
+ ],
+ "download_subtitle": true,
+ "merge_subs": true,
+ "specific_list_subtitles": [
+ "ita",
+ "eng"
+ ],
+ "cleanup_tmp_folder": true
+ },
+ "M3U8_CONVERSION": {
+ "use_codec": false,
+ "use_vcodec": true,
+ "use_acodec": true,
+ "use_bitrate": true,
+ "use_gpu": false,
+ "default_preset": "ultrafast"
+ },
+ "M3U8_PARSER": {
+ "force_resolution": "Best",
+ "get_only_link": false
+ },
+ "REQUESTS": {
+ "verify": false,
+ "timeout": 20,
+ "max_retry": 8
+ }
+}
diff --git a/StreamingCommunity/TelegramHelp/telegram_bot.py b/StreamingCommunity/TelegramHelp/telegram_bot.py
index d24b68d..85eb4c9 100644
--- a/StreamingCommunity/TelegramHelp/telegram_bot.py
+++ b/StreamingCommunity/TelegramHelp/telegram_bot.py
@@ -575,6 +575,10 @@ class TelegramBot:
cleaned_output = cleaned_output.replace(
"\n\n", "\n"
) # Rimuovi newline multipli
+
+ # Inizializza le variabili
+ cleaned_output_0 = None # o ""
+ cleaned_output_1 = None # o ""
# Dentro cleaned_output c'รจ una stringa recupero quello che si trova tra ## ##
download_section = re.search(r"##(.*?)##", cleaned_output, re.DOTALL)