mirror of
https://github.com/Arrowar/StreamingCommunity.git
synced 2025-06-03 10:00:10 +00:00
Feat/app api and frontend (#140)
* minor fixes * created basic django app * add django dependency * created basic search endpoint * created retrieve method for search * remove retrieve * start implementing download endpoint (only movie for now) * start implementing episode info for series * finished get_episodes_info * minor fixes * add download anime episode * start implementing download for tv series * refactor methods * finished download endpoint (will implement possibility to download single episodes of season in tv series) * new domain and black on project * start * add cors * add start gui command * add gui for search * edited .gitignore * create component for media details * better UX/UI * edited anime episode to stream response (better experience) * implemented UI for media details (TODO add download capabilities) * fix poster fetching * minor fixes * fix cors error * start implementing download * fix typing on anime movies * refactor * refactor + add download OVA * add plot for all anime types * add download for all anime episodes * add download all tv series episodes * fix crach if localStorage is undefined * moved download logic in separeted file * fix wrong index passed while downloading tv series * fix style searchbar * add loader to search button and add enter listener while searching * remove dependency from loading episodes to download all in anime series * add function to download selected episodes for anime * add sh command to kill gui * fix messages in kill_gui.sh * start implementing download select episodes for tv series (to be tested) + run black and eslint * start refactoring to version 2.0 * start implementing preview endpoint * finish reimplement version 2.0
This commit is contained in:
parent
306377a7be
commit
1c5f960b16
@ -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)
|
||||
)
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
'''
|
||||
|
@ -148,7 +148,7 @@ const downloadAllItems = async () => {
|
||||
@click.prevent="downloadAllItems">
|
||||
Scarica {{['TV_ANIME', 'TV'].includes(item.type)? 'tutto' : ''}}
|
||||
</button>
|
||||
<template v-if="!loading && ['TV_ANIME', 'TV'].includes(item.type)">
|
||||
<!--<template v-if="!loading && ['TV_ANIME', 'TV'].includes(item.type)">
|
||||
<button @click="toggleEpisodeSelection">
|
||||
{{selectingEpisodes ? 'Disattiva' : 'Attiva'}} selezione episodi
|
||||
</button>
|
||||
@ -156,7 +156,7 @@ const downloadAllItems = async () => {
|
||||
@click="downloadSelectedEpisodes">
|
||||
Download episodi selezionati
|
||||
</button>
|
||||
</template>
|
||||
</template>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -194,7 +194,7 @@ const downloadAllItems = async () => {
|
||||
|
||||
<!--MOVIES SECTION-->
|
||||
<div v-else-if="!loading && ['MOVIE', 'OVA', 'SPECIAL'].includes(item.type)">
|
||||
<p>Questo è un {{item.type}} (QUESTO TESTO E' A SCOPO DI TEST)</p>
|
||||
<!-- WILL BE POPULATED WITH HYPOTETICAL MOVIES CONTENT -->
|
||||
</div>
|
||||
|
||||
<!--LOADING SECTION-->
|
||||
|
Loading…
x
Reference in New Issue
Block a user