mirror of
https://github.com/Arrowar/StreamingCommunity.git
synced 2025-06-01 17:10:10 +00:00
Fix telegram and proxy (#322)
* Add ENABLE_VIDEO * Fix proxy * Add error proxy * Update config.json * Fix telegram_bot (#312) * Update config.json * Fix telegram_bot * fix bug * Fix StreamingCommunity site * Delete console.log * fix doppio string_to_search * Update __init__.py * Update site.py * Update config.json * Update site.py * Update config.json * Update __init__.py * Update __init__.py * Fix proxy (#319) * Add ENABLE_VIDEO * Fix proxy * Add error proxy * Update config.json * Refactor user input handling and improve messaging in __init__.py --------- Co-authored-by: None <62809003+Arrowar@users.noreply.github.com> Co-authored-by: l1n00 <> * Fix proxy __init__ * Update os.py --------- Co-authored-by: l1n00 <delmolinonicola@gmail.com>
This commit is contained in:
parent
dfcc29078f
commit
1c89398054
18
README.md
18
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.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>🤖 Bot Commands</summary>
|
||||
|
||||
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 <ID>
|
||||
- View the real-time output of a download using /screen <ID>
|
||||
|
||||
Stop an incorrect download using /stop <ID>.
|
||||
|
||||
View the real-time output of a download using /screen <ID>.
|
||||
|
||||
⚠ 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.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>🔧 Environment Setup</summary>
|
||||
🛠 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
|
||||
|
@ -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}")
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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",
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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_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
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
return media_search_manager.get_length()
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
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
|
||||
|
@ -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())
|
||||
|
62
StreamingCommunity/TelegramHelp/config.json
Normal file
62
StreamingCommunity/TelegramHelp/config.json
Normal file
@ -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
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user