From 3e5b126c07edad081454f5c3b6379bb365700544 Mon Sep 17 00:00:00 2001 From: RubyTemple <28711906+RubyTemple@users.noreply.github.com> Date: Mon, 17 Mar 2025 11:55:52 +0100 Subject: [PATCH] api: Integration with Altadefinizione, AnimeUnity and Telegram bot improvements (#288) * Fixed issues related to TV series for the Telegram bot. * Fixed issues related to TV series for the Telegram bot. * feat: Integrate Telegram bot support for animeunity and altadefinizione * api: From cb01blog to cb01new (cherry picked from commit 477637ee5c848c5860a85939fbf6393b6cc2d3dd) * mp4: Fix error 'set_alpn_protocols' (cherry picked from commit ab094d0b1db21e74b8af4b5b995779dfd88ce3db) * api: Add warning altadefinizione (cherry picked from commit 870714ca7e88d26be1fc5530cf5ba90c69f1c296) * Solved Unexpected error: 'int' object has no attribute 'set_alpn_protocols' * Update series.py --------- Co-authored-by: RubyTemple Co-authored-by: Lovi <62809003+Lovi-0@users.noreply.github.com> Co-authored-by: None <62809003+Arrowar@users.noreply.github.com> --- .../Api/Site/altadefinizione/__init__.py | 43 ++++++++++---- .../Api/Site/altadefinizione/film.py | 30 +++++++++- .../Api/Site/altadefinizione/series.py | 59 ++++++++++++++++--- .../Api/Site/altadefinizione/site.py | 27 ++++++++- .../Site/altadefinizione/util/ScrapeSerie.py | 2 +- .../Api/Site/animeunity/film_serie.py | 6 +- .../Api/Site/streamingcommunity/site.py | 4 ++ .../Lib/Downloader/HLS/segments.py | 2 +- 8 files changed, 147 insertions(+), 26 deletions(-) diff --git a/StreamingCommunity/Api/Site/altadefinizione/__init__.py b/StreamingCommunity/Api/Site/altadefinizione/__init__.py index 8373379..4a6ae3c 100644 --- a/StreamingCommunity/Api/Site/altadefinizione/__init__.py +++ b/StreamingCommunity/Api/Site/altadefinizione/__init__.py @@ -1,24 +1,24 @@ -# 21.05.24 +# 16.03.25 + +import sys +import subprocess from urllib.parse import quote_plus - # External library from rich.console import Console from rich.prompt import Prompt - # Internal utilities from StreamingCommunity.Api.Template import get_select_title - # Logic class from StreamingCommunity.Api.Template.config_loader import site_constant +from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance from .site import title_search, table_show_manager, media_search_manager from .film import download_film from .series import download_series - # Variable indice = 2 _useFor = "film_serie" @@ -34,28 +34,47 @@ def search(string_to_search: str = None, get_onylDatabase: bool = False): """ Main function of the application for film and series. """ - if string_to_search is None: - string_to_search = msg.ask(f"\n[purple]Insert word to search in [green]{site_constant.SITE_NAME}").strip() + + if site_constant.TELEGRAM_BOT: + bot = get_bot_instance() + + if string_to_search is None: + + # Chiedi la scelta all'utente con il bot Telegram + string_to_search = bot.ask( + "key_search", + f"Inserisci la parola da cercare\noppure back per tornare alla scelta: ", + None + ) + + if string_to_search == 'back': + # Riavvia lo script + # Chiude il processo attuale e avvia una nuova istanza dello script + subprocess.Popen([sys.executable] + sys.argv) + sys.exit() + else: + if string_to_search is None: + string_to_search = msg.ask(f"\n[purple]Insert word to search in [green]{site_constant.SITE_NAME}").strip() len_database = title_search(quote_plus(string_to_search)) # Return list of elements if get_onylDatabase: return media_search_manager - + if len_database > 0: # Select title from list select_title = get_select_title(table_show_manager, media_search_manager) - + if select_title.type == 'tv': download_series(select_title) - + else: download_film(select_title) - + else: console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}") # Retry - search() \ No newline at end of file + search() diff --git a/StreamingCommunity/Api/Site/altadefinizione/film.py b/StreamingCommunity/Api/Site/altadefinizione/film.py index 296c0d1..c5c86c1 100644 --- a/StreamingCommunity/Api/Site/altadefinizione/film.py +++ b/StreamingCommunity/Api/Site/altadefinizione/film.py @@ -8,7 +8,7 @@ import httpx from bs4 import BeautifulSoup from rich.console import Console - +from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance, TelegramSession # Internal utilities from StreamingCommunity.Util.os import os_manager from StreamingCommunity.Util.message import start_message @@ -41,6 +41,19 @@ def download_film(select_title: MediaItem) -> str: Return: - str: output path if successful, otherwise None """ + + if site_constant.TELEGRAM_BOT: + bot = get_bot_instance() + bot.send_message(f"Download in corso:\n{select_title.name}", None) + + # Viene usato per lo screen + console.print(f"## Download: [red]{select_title.name} ##") + + # Get script_id + script_id = TelegramSession.get_session() + if script_id != "unknown": + TelegramSession.updateScriptId(script_id, select_title.name) + start_message() console.print(f"[yellow]Download: [red]{select_title.name} \n") @@ -51,6 +64,9 @@ def download_film(select_title: MediaItem) -> str: except Exception as e: console.print(f"[red]Error fetching the page: {e}") + + if site_constant.TELEGRAM_BOT: + bot.send_message(f"ERRORE\n\nErrore durante il recupero della pagina.\n\n{e}", None) return None # Create mostraguarda url @@ -59,6 +75,8 @@ def download_film(select_title: MediaItem) -> str: url_mostraGuarda = iframe_tag[0].get('data-src') if not url_mostraGuarda: console.print("Error: data-src attribute not found in iframe.") + if site_constant.TELEGRAM_BOT: + bot.send_message(f"ERRORE\n\nErrore: attributo data-src non trovato nell'iframe", None) # Extract supervideo URL try: @@ -68,6 +86,9 @@ def download_film(select_title: MediaItem) -> str: except Exception as e: console.print(f"[red]Error fetching mostraguarda link: {e}") console.print("[yellow]Missing access credentials. This part of the code is still under development.") + if site_constant.TELEGRAM_BOT: + bot.send_message(f"ERRORE\n\nErrore durante il recupero del link mostra/guarda.\n\n{e}", None) + bot.send_message(f"ERRORE\n\nCredenziali di accesso mancanti.\nQuesta parte del codice รจ ancora in fase di sviluppo.", None) return None # Create supervio URL @@ -92,6 +113,13 @@ def download_film(select_title: MediaItem) -> str: output_path=os.path.join(mp4_path, title_name) ).start() + if site_constant.TELEGRAM_BOT: + + # Delete script_id + script_id = TelegramSession.get_session() + if script_id != "unknown": + TelegramSession.deleteScriptId(script_id) + if r_proc['error'] is not None: try: os.remove(r_proc['path']) except: pass diff --git a/StreamingCommunity/Api/Site/altadefinizione/series.py b/StreamingCommunity/Api/Site/altadefinizione/series.py index 3db234d..242bff4 100644 --- a/StreamingCommunity/Api/Site/altadefinizione/series.py +++ b/StreamingCommunity/Api/Site/altadefinizione/series.py @@ -12,6 +12,8 @@ from rich.prompt import Prompt # Internal utilities from StreamingCommunity.Util.message import start_message from StreamingCommunity.Lib.Downloader import HLS_Downloader +from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance, TelegramSession + # Logic class from .util.ScrapeSerie import GetSerieInfo @@ -56,9 +58,23 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra console.print(f"[yellow]Download: [red]{index_season_selected}:{index_episode_selected} {obj_episode.name}") print() + if site_constant.TELEGRAM_BOT: + bot = get_bot_instance() + + # Invio a telegram + bot.send_message( + f"Download in corso\nSerie: {scrape_serie.series_name}\nStagione: {index_season_selected}\nEpisodio: {index_episode_selected}\nTitolo: {obj_episode.name}", + None + ) + + # Get script_id and update it + script_id = TelegramSession.get_session() + if script_id != "unknown": + TelegramSession.updateScriptId(script_id, f"{scrape_serie.series_name} - S{index_season_selected} - E{index_episode_selected} - {obj_episode.name}") + # Define filename and path for the downloaded video - mp4_name = f"{map_episode_title(scrape_serie.serie_name, index_season_selected, index_episode_selected, obj_episode.name)}.mp4" - mp4_path = os.path.join(site_constant.SERIES_FOLDER, scrape_serie.serie_name, f"S{index_season_selected}") + 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(site_constant.SERIES_FOLDER, scrape_serie.series_name, f"S{index_season_selected}") # Retrieve scws and if available master playlist video_source = VideoSource(obj_episode.url) @@ -127,6 +143,9 @@ def download_series(select_season: MediaItem) -> None: Parameters: - select_season (MediaItem): Selected media item (TV series). """ + if site_constant.TELEGRAM_BOT: + bot = get_bot_instance() + start_message() # Init class @@ -138,10 +157,28 @@ def download_series(select_season: MediaItem) -> None: # Prompt user for season selection and download episodes console.print(f"\n[green]Seasons found: [red]{seasons_count}") - index_season_selected = msg.ask( - "\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, " - "[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end" - ) + + if site_constant.TELEGRAM_BOT: + console.print("\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, " + "[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end") + + bot.send_message(f"Stagioni trovate: {seasons_count}", None) + + index_season_selected = bot.ask( + "select_title_episode", + "Menu di selezione delle stagioni\n\n" + "- Inserisci il numero della stagione (ad esempio, 1)\n" + "- Inserisci * per scaricare tutte le stagioni\n" + "- Inserisci un intervallo di stagioni (ad esempio, 1-2) per scaricare da una stagione all'altra\n" + "- Inserisci (ad esempio, 3-*) per scaricare dalla stagione specificata fino alla fine della serie", + None + ) + + else: + index_season_selected = msg.ask( + "\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, " + "[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end" + ) # Manage and validate the selection list_season_select = manage_selection(index_season_selected, seasons_count) @@ -161,4 +198,12 @@ def download_series(select_season: MediaItem) -> None: else: # Otherwise, let the user select specific episodes for the single season - download_episode(i_season, scrape_serie, download_all=False) \ No newline at end of file + download_episode(i_season, scrape_serie, download_all=False) + + if site_constant.TELEGRAM_BOT: + bot.send_message(f"Finito di scaricare tutte le serie e episodi", None) + + # Get script_id + script_id = TelegramSession.get_session() + if script_id != "unknown": + TelegramSession.deleteScriptId(script_id) diff --git a/StreamingCommunity/Api/Site/altadefinizione/site.py b/StreamingCommunity/Api/Site/altadefinizione/site.py index 64b1e0f..8117e90 100644 --- a/StreamingCommunity/Api/Site/altadefinizione/site.py +++ b/StreamingCommunity/Api/Site/altadefinizione/site.py @@ -6,7 +6,7 @@ import httpx from bs4 import BeautifulSoup from rich.console import Console - +from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance # Internal utilities from StreamingCommunity.Util.config_json import config_manager from StreamingCommunity.Util.headers import get_userAgent @@ -35,6 +35,9 @@ def title_search(title_search: str) -> int: Returns: int: The number of titles found. """ + if site_constant.TELEGRAM_BOT: + bot = get_bot_instance() + media_search_manager.clear() table_show_manager.clear() @@ -47,14 +50,22 @@ def title_search(title_search: str) -> int: except Exception as e: console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}") + if site_constant.TELEGRAM_BOT: + bot.send_message(f"ERRORE\n\nErrore nella richiesta di ricerca:\n\n{e}", None) return 0 - + + # Prepara le scelte per l'utente + if site_constant.TELEGRAM_BOT: + choices = [] + # Create soup istance soup = BeautifulSoup(response.text, "html.parser") + i = 0 + # Collect data from soup for movie_div in soup.find_all("div", class_="movie"): - + title_tag = movie_div.find("h2", class_="movie-title") title = title_tag.find("a").get_text(strip=True) url = title_tag.find("a").get("href") @@ -70,6 +81,16 @@ def title_search(title_search: str) -> int: 'name': title, 'type': tipo }) + + if site_constant.TELEGRAM_BOT: + choice_text = f"{i} - {title} ({tipo})" + choices.append(choice_text) + + i += 1 + + if site_constant.TELEGRAM_BOT: + if choices: + 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 diff --git a/StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py b/StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py index b57c15d..c41fa9c 100644 --- a/StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py +++ b/StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py @@ -34,7 +34,7 @@ class GetSerieInfo: """ response = httpx.get(self.url, headers=self.headers) soup = BeautifulSoup(response.text, "html.parser") - self.serie_name = soup.find("title").get_text(strip=True).split(" - ")[0] + self.series_name = soup.find("title").get_text(strip=True).split(" - ")[0] # Process all seasons season_items = soup.find_all('div', class_='accordion-item') diff --git a/StreamingCommunity/Api/Site/animeunity/film_serie.py b/StreamingCommunity/Api/Site/animeunity/film_serie.py index 520c5e0..9cb9a9e 100644 --- a/StreamingCommunity/Api/Site/animeunity/film_serie.py +++ b/StreamingCommunity/Api/Site/animeunity/film_serie.py @@ -123,7 +123,11 @@ def download_series(select_title: MediaItem): last_command = bot.ask( "select_title", - f"Inserisci l'indice del media o * per scaricare tutti i media, oppure 1-2 o 3-* per un intervallo di media.", + "Menu di selezione degli episodi: \n\n" + "- Inserisci il numero dell'episodio (ad esempio, 1)\n" + "- Inserisci * per scaricare tutti gli episodi\n" + "- Inserisci un intervallo di episodi (ad esempio, 1-2) per scaricare da un episodio all'altro\n" + "- Inserisci (ad esempio, 3-*) per scaricare dall'episodio specificato fino alla fine della serie", None ) diff --git a/StreamingCommunity/Api/Site/streamingcommunity/site.py b/StreamingCommunity/Api/Site/streamingcommunity/site.py index 1564315..700e8c6 100644 --- a/StreamingCommunity/Api/Site/streamingcommunity/site.py +++ b/StreamingCommunity/Api/Site/streamingcommunity/site.py @@ -52,6 +52,8 @@ def title_search(title_search: str) -> int: except Exception as e: console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}") + if site_constant.TELEGRAM_BOT: + bot.send_message(f"ERRORE\n\nErrore nella richiesta di ricerca:\n\n{e}", None) return 0 # Prepara le scelte per l'utente @@ -82,6 +84,8 @@ def title_search(title_search: str) -> int: except Exception as e: print(f"Error parsing a film entry: {e}") + if site_constant.TELEGRAM_BOT: + bot.send_message(f"ERRORE\n\nErrore nell'analisi del film:\n\n{e}", None) if site_constant.TELEGRAM_BOT: if choices: diff --git a/StreamingCommunity/Lib/Downloader/HLS/segments.py b/StreamingCommunity/Lib/Downloader/HLS/segments.py index 3f2756c..2cf2088 100644 --- a/StreamingCommunity/Lib/Downloader/HLS/segments.py +++ b/StreamingCommunity/Lib/Downloader/HLS/segments.py @@ -37,7 +37,7 @@ from ...M3U8 import ( # Config TQDM_DELAY_WORKER = config_manager.get_float('M3U8_DOWNLOAD', 'tqdm_delay') REQUEST_MAX_RETRY = config_manager.get_int('REQUESTS', 'max_retry') -REQUEST_VERIFY = config_manager.get_int('REQUESTS', 'verify') +REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify') DEFAULT_VIDEO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_video_workser') DEFAULT_AUDIO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_audio_workser') MAX_TIMEOOUT = config_manager.get_int("REQUESTS", "timeout")