diff --git a/Src/Api/Animeunity/anime.py b/Src/Api/Animeunity/anime.py index 26a6357..e250a89 100644 --- a/Src/Api/Animeunity/anime.py +++ b/Src/Api/Animeunity/anime.py @@ -26,37 +26,40 @@ video_source = VideoSource() -def download_episode(index_select: int): +def download_episode(index_select: int, custom_video_source: VideoSource = None): """ Downloads the selected episode. Args: - index_select (int): Index of the episode to download. """ + + active_video_source = custom_video_source if custom_video_source is not None else video_source + # Get information about the selected episode - obj_episode = video_source.get_info_episode(index_select) + obj_episode = active_video_source.get_info_episode(index_select) start_message() console.print(f"[yellow]Download: [red]EP_{obj_episode.number} \n") # Get the embed URL for the episode - embed_url = video_source.get_embed(obj_episode.id) + embed_url = active_video_source.get_embed(obj_episode.id) # Parse parameter in embed text - video_source.parse_script(embed_url) + active_video_source.parse_script(embed_url) # Create output path mp4_path = None mp4_name = f"{index_select + 1}.mp4" - if video_source.is_series: - mp4_path = os.path.join(ROOT_PATH, ANIME_FOLDER, SERIES_FOLDER, video_source.series_name) + if active_video_source.is_series: + mp4_path = os.path.join(ROOT_PATH, ANIME_FOLDER, SERIES_FOLDER, active_video_source.series_name) else: - mp4_path = os.path.join(ROOT_PATH, ANIME_FOLDER, MOVIE_FOLDER, video_source.series_name) + mp4_path = os.path.join(ROOT_PATH, ANIME_FOLDER, MOVIE_FOLDER, active_video_source.series_name) # Crete downloader obj_download = Downloader( - m3u8_playlist = video_source.get_playlist(), + m3u8_playlist = active_video_source.get_playlist(), output_filename = os.path.join(mp4_path, mp4_name) ) diff --git a/Src/Api/Streamingcommunity/series.py b/Src/Api/Streamingcommunity/series.py index f10be43..0046e35 100644 --- a/Src/Api/Streamingcommunity/series.py +++ b/Src/Api/Streamingcommunity/series.py @@ -66,7 +66,7 @@ def display_episodes_list() -> str: return last_command -def donwload_video(tv_name: str, index_season_selected: int, index_episode_selected: int) -> None: +def donwload_video(tv_name: str, index_season_selected: int, index_episode_selected: int, custom_video_source: VideoSource = None) -> None: """ Download a single episode video. @@ -76,10 +76,12 @@ def donwload_video(tv_name: str, index_season_selected: int, index_episode_selec - index_episode_selected (int): Index of the selected episode. """ + active_video_source = custom_video_source if custom_video_source is not None else video_source + start_message() # Get info about episode - obj_episode = video_source.obj_episode_manager.episodes[index_episode_selected - 1] + obj_episode = active_video_source.obj_episode_manager.episodes[index_episode_selected - 1] console.print(f"[yellow]Download: [red]{index_season_selected}:{index_episode_selected} {obj_episode.name}") print() @@ -88,9 +90,9 @@ def donwload_video(tv_name: str, index_season_selected: int, index_episode_selec mp4_path = os.path.join(ROOT_PATH, STREAMING_FOLDER, SERIES_FOLDER, tv_name, f"S{index_season_selected}") # Retrieve scws and if available master playlist - video_source.get_iframe(obj_episode.id) - video_source.get_content() - master_playlist = video_source.get_playlist() + active_video_source.get_iframe(obj_episode.id) + active_video_source.get_content() + master_playlist = active_video_source.get_playlist() # Download the episode Downloader( @@ -99,7 +101,7 @@ def donwload_video(tv_name: str, index_season_selected: int, index_episode_selec ).start(SERVER_IP) -def donwload_episode(tv_name: str, index_season_selected: int, donwload_all: bool = False) -> None: +def donwload_episode(tv_name: str, index_season_selected: int, donwload_all: bool = False, custom_video_source: VideoSource = None) -> None: """ Download all episodes of a season. @@ -109,19 +111,21 @@ def donwload_episode(tv_name: str, index_season_selected: int, donwload_all: boo - donwload_all (bool): Donwload all seasons episodes """ + active_video_source = custom_video_source if custom_video_source is not None else video_source + # Clean memory of all episodes and get the number of the season (some dont follow rule of [1,2,3,4,5] but [1,2,3,145,5,6,7]). - video_source.obj_episode_manager.clear() - season_number = (video_source.obj_title_manager.titles[index_season_selected-1].number) + active_video_source.obj_episode_manager.clear() + season_number = (active_video_source.obj_title_manager.titles[index_season_selected-1].number) # Start message and collect information about episodes start_message() - video_source.collect_title_season(season_number) - episodes_count = video_source.obj_episode_manager.get_length() + active_video_source.collect_title_season(season_number) + episodes_count = active_video_source.obj_episode_manager.get_length() # Download all episodes wihtout ask if donwload_all: for i_episode in range(1, episodes_count+1): - donwload_video(tv_name, index_season_selected, i_episode) + donwload_video(tv_name, index_season_selected, i_episode, active_video_source) console.print(f"\n[red]Download [yellow]season: [red]{index_season_selected}.") @@ -134,12 +138,12 @@ def donwload_episode(tv_name: str, index_season_selected: int, donwload_all: boo # Download selected episodes if len(list_episode_select) == 1 and last_command != "*": - donwload_video(tv_name, index_season_selected, list_episode_select[0]) + donwload_video(tv_name, index_season_selected, list_episode_select[0],active_video_source) # Download all other episodes selecter else: for i_episode in list_episode_select: - donwload_video(tv_name, index_season_selected, i_episode) + donwload_video(tv_name, index_season_selected, i_episode, active_video_source) def download_series(tv_id: str, tv_name: str, version: str, domain: str) -> None: diff --git a/Src/Lib/Hls/segments.py b/Src/Lib/Hls/segments.py index beeb831..e69f28d 100644 --- a/Src/Lib/Hls/segments.py +++ b/Src/Lib/Hls/segments.py @@ -319,7 +319,11 @@ class M3U8_Segments: self.condition.notify_all() # Wake up the writer thread if it's waiting # Register the signal handler for Ctrl+C - signal.signal(signal.SIGINT, signal_handler) + try: + signal.signal(signal.SIGINT, signal_handler) + except Exception as e: + logging.error(f"Failed to register signal handler: {e}") + logging.error("Ctrl+C detection may not work.") with ThreadPoolExecutor(max_workers=TQDM_MAX_WORKER) as executor: diff --git a/api/endpoints/urls.py b/api/endpoints/urls.py index 184bb2f..8d2802c 100644 --- a/api/endpoints/urls.py +++ b/api/endpoints/urls.py @@ -1,10 +1,10 @@ from rest_framework import routers -from .views import SearchView#, DownloadView +from .views import SearchView, DownloadView router = routers.DefaultRouter() router.register(r"search", SearchView, basename="search") -#router.register(r"download", DownloadView, basename="download") +router.register(r"download", DownloadView, basename="download") urlpatterns = router.urls diff --git a/api/endpoints/views.py b/api/endpoints/views.py index 0df7062..8c7df92 100644 --- a/api/endpoints/views.py +++ b/api/endpoints/views.py @@ -7,10 +7,16 @@ from rest_framework import viewsets from rest_framework.decorators import action from rest_framework.response import Response + +from Src.Api.Animeunity.anime import donwload_film +from Src.Api.Animeunity.anime import download_episode as donwload_anime_episode from Src.Api.Animeunity import title_search as anime_search from Src.Api.Animeunity.Core.Vix_player.player import VideoSource as anime_source from Src.Api.Animeunity.site import media_search_manager as anime_media_manager + +from Src.Api.Streamingcommunity.film import download_film +from Src.Api.Streamingcommunity.series import donwload_episode as download_tv_episode from Src.Api.Streamingcommunity import title_search as sc_search, get_version_and_domain from Src.Api.Streamingcommunity.Core.Vix_player.player import VideoSource as film_video_source from Src.Api.Streamingcommunity.site import media_search_manager as film_media_manager @@ -151,7 +157,7 @@ class SearchView(viewsets.ViewSet): return Response({"error": "No media found with that search query"}) -''' + class DownloadView(viewsets.ViewSet): def create(self, request): @@ -171,59 +177,36 @@ class DownloadView(viewsets.ViewSet): case "MOVIE": download_film(self.media_id, self.media_slug, self.domain) case "TV": - video_source = VideoSource() - video_source.set_url_base_name(STREAM_SITE_NAME) - video_source.set_version(self.site_version) - video_source.set_domain(self.domain) - video_source.set_series_name(self.media_slug) - video_source.set_media_id(self.media_id) + video_source = film_video_source() + video_source.setup( + version = self.site_version, + domain = self.domain, + media_id = self.media_id, + series_name = self.media_slug + ) video_source.collect_info_seasons() video_source.obj_episode_manager.clear() - video_source.collect_title_season(self.download_id) - episodes_count = video_source.obj_episode_manager.get_length() - for i_episode in range(1, episodes_count + 1): - episode_id = video_source.obj_episode_manager.episodes[ - i_episode - 1 - ].id + seasons_count = video_source.obj_title_manager.get_length() - # Define filename and path for the downloaded video - mp4_name = remove_special_characters( - f"{map_episode_title(self.media_slug,video_source.obj_episode_manager.episodes[i_episode - 1],self.download_id)}.mp4" - ) - mp4_path = remove_special_characters( - os.path.join( - ROOT_PATH, - SERIES_FOLDER, - self.media_slug, - f"S{self.download_id}", - ) - ) - os.makedirs(mp4_path, exist_ok=True) - - # Get iframe and content for the episode - video_source.get_iframe(episode_id) - video_source.get_content() - video_source.set_url_base_name(STREAM_SITE_NAME) - - # Download the episode - obj_download = Downloader( - m3u8_playlist=video_source.get_playlist(), - key=video_source.get_key(), - output_filename=os.path.join(mp4_path, mp4_name), - ) - - obj_download.download_m3u8() + for i_season in range(1, seasons_count + 1): + download_tv_episode(self.media_slug, i_season, True, video_source) case "TV_ANIME": - episodes_downloader = EpisodeDownloader( - self.media_id, self.media_slug + video_source = anime_source() + video_source.setup( + media_id = self.media_id, + series_name = self.media_slug ) - episodes_downloader.download_episode(self.download_id) + episoded_count = video_source.get_count_episodes() + for i in range(episoded_count): + donwload_anime_episode(i, video_source) case "OVA" | "SPECIAL": - anime_download_film( - id_film=self.media_id, title_name=self.media_slug + donwload_film( + id_film=self.media_id, + title_name=self.media_slug + ) case _: raise Exception("Type media not supported") @@ -238,4 +221,3 @@ class DownloadView(viewsets.ViewSet): } return Response(response_dict) -''' diff --git a/frontend/src/views/Details.vue b/frontend/src/views/Details.vue index 5880730..9e6a95e 100644 --- a/frontend/src/views/Details.vue +++ b/frontend/src/views/Details.vue @@ -148,7 +148,7 @@ const downloadAllItems = async () => { @click.prevent="downloadAllItems"> Scarica {{['TV_ANIME', 'TV'].includes(item.type)? 'tutto' : ''}} -