diff --git a/app/download.py b/app/download.py index e6d3b40..3af7696 100644 --- a/app/download.py +++ b/app/download.py @@ -134,22 +134,24 @@ class dropout(): with ArchiveOnlyYDL(dl_opts) as ydl: ydl.download([playlist_url]) - def show(show, season, episode_start=None): - directory = f'/tv/{show}/Season {season}/' - if not os.path.exists(directory): - os.makedirs(directory) + def show(show, season, specials=False, episode_start=None): + season_str = f"{int(season):02}" if not specials else "00" + directory = f"/tv/{show}/{'Specials' if specials else f'Season {season}'}" + os.makedirs(directory, exist_ok=True) with open('/data/dropout.json', 'r') as json_file: url_mapping = json.load(json_file) + url = next((item['URL'] for item in url_mapping if item['SHOW'] == show), None) if url is None: raise ValueError(f"Show '{show}' not found in the JSON data.") playlist_url = f'{url}/season:{season}' - - # Create match_filter + + # Match filter logic filter_pattern = ( - "title !~= " + "title " + f"{'~=' if specials else '!~='} " r"'(?i).*behind.?the.?scenes.*" r"|.*trailer.*" r"|.*recap.*" @@ -163,22 +165,18 @@ class dropout(): 'cookiefile': '/data/dropout.cookies.txt', } - # Step 1: Extract playlist info + # Extract playlist info with yt_dlp.YoutubeDL(ydl_opts) as ydl: playlist_info = ydl.extract_info(playlist_url, download=False) entries = playlist_info.get('entries', []) - filtered_entries = [] - for entry in entries: - if match_filter(entry) is None: # Not filtered out - filtered_entries.append(entry) + filtered_entries = [entry for entry in entries if match_filter(entry) is None] - # Step 2: Download filtered entries with corrected episode numbers episode_start = int(episode_start) if episode_start else 1 for i, entry in enumerate(filtered_entries, start=episode_start): episode_number = f"{i:02}" - filename_template = f"{show} - S{int(season):02}E{episode_number} - %(title)s.%(ext)s" + filename_template = f"{show} - S{season_str}E{episode_number} - %(title)s.%(ext)s" dl_opts = { 'progress_hooks': [my_hook], @@ -198,70 +196,6 @@ class dropout(): with yt_dlp.YoutubeDL(dl_opts) as ydl: ydl.download([entry['webpage_url']]) - def specials(show, season, episode_start): - directory = f'/tv/{show}/Specials/' - if not os.path.exists(directory): - os.makedirs(directory) - - with open('/data/dropout.json', 'r') as json_file: - url_mapping = json.load(json_file) - url = next((item['URL'] for item in url_mapping if item['SHOW'] == show), None) - if url is None: - raise ValueError(f"Show '{show}' not found in the JSON data.") - - playlist_url = f'{url}/season:{season}' - - # Create match_filter - filter_pattern = ( - "title ~= " - r"'(?i).*behind.?the.?scenes.*" - r"|.*trailer.*" - r"|.*recap.*" - r"|.*last.looks.*'" - ) - match_filter = yt_dlp.utils.match_filter_func(filter_pattern) - - ydl_opts = { - 'quiet': True, - 'skip_download': True, - 'cookiefile': '/data/dropout.cookies.txt', - } - - # Step 1: Extract playlist info - with yt_dlp.YoutubeDL(ydl_opts) as ydl: - playlist_info = ydl.extract_info(playlist_url, download=False) - - entries = playlist_info.get('entries', []) - filtered_entries = [] - for entry in entries: - if match_filter(entry) is None: # Not filtered out - filtered_entries.append(entry) - - # Step 2: Download filtered entries with corrected episode numbers - episode_start = int(episode_start) if episode_start else 1 - - for i, entry in enumerate(filtered_entries, start=episode_start): - episode_number = f"{i:02}" - filename_template = f"{show} - S00E{episode_number} - %(title)s.%(ext)s" - - dl_opts = { - 'progress_hooks': [my_hook], - 'download_archive': '/data/logs/dropout.archive.text', - 'format': 'bestvideo+bestaudio/best', - 'audio_quality': '256K', - 'paths': { - 'temp': '/temp', - 'home': directory - }, - 'cookiefile': '/data/dropout.cookies.txt', - 'writesubtitles': True, - 'subtitleslangs': ['en'], - 'outtmpl': filename_template, - } - - with yt_dlp.YoutubeDL(dl_opts) as ydl: - ydl.download([entry['webpage_url']]) - def series(force_download): json_data=[] @@ -302,7 +236,7 @@ class youtube(): logger.info(f'message=Received download request for {url}.') dl_ops = { 'progress_hooks': [my_hook], - 'download_archive': '/data/logs/youtube.archive.text', + 'download_archive': '/data/logs/youtube.archive.log', 'paths': { 'temp': '/temp', 'home': location diff --git a/app/main.py b/app/main.py index 9495975..cd6c028 100644 --- a/app/main.py +++ b/app/main.py @@ -131,7 +131,9 @@ async def dropout_download( show: str = Form(...), season: Optional[int] = Form(None), latest: bool = Form(False), - archive: bool = Form(False) + archive: bool = Form(False), + specials: bool = Form(False), + episode_start: Optional[int] = Form(None) ): try: # Resolve latest season if requested @@ -157,15 +159,14 @@ async def dropout_download( content={"status": "error", "message": "Season is required unless 'latest' is used."} ) - - task_msg = f"{'Adding to archive' if archive else 'Starting download'} for show '{show}', season {season}." + task_msg = f"{'Adding to archive' if archive else 'Starting download'} for show '{show}', season {season}{' specials' if specials else ''}." logger.info(f"message={task_msg}") # Schedule the background task if archive: background_tasks.add_task(download.dropout.archive, show, season) else: - background_tasks.add_task(download.dropout.show, show, season) + background_tasks.add_task(download.dropout.show, show, season, specials, episode_start) return JSONResponse( status_code=200, @@ -174,13 +175,11 @@ async def dropout_download( "message": ( f"Series is being added to the completed archive for '{show}', season {season}." if archive else - f"Series download started for '{show}', season {season}." + f"Series download started for '{show}', season {season}{' specials' if specials else ''}." ) } ) - - except Exception as e: logger.exception(f"Unhandled exception during /dropout/download: {e}") return JSONResponse( @@ -188,20 +187,20 @@ async def dropout_download( content={"status": "error", "message": "An unexpected error occurred."} ) -@app.post("/dropout/download/specials", description="Downloads a seasons behind the scenes and trailers, ignores main episodes.") -async def dropoutDownload( - background_tasks: BackgroundTasks, - show: str = Form(...), - season: int = Form(...), - episode: Optional[int] = Form(None) -): - try: - logger.info(f'message=Received download request for specials of season {season} of {show}.') - background_tasks.add_task(download.dropout.specials,show,season,episode) - # download.dropout.show(show,season,episode) - return JSONResponse(status_code=200, content={"status": "success", "message": "Series downloaded."}) - except Exception as e: - return JSONResponse(status_code=500, content={"status": "error", "message": str(e)}) +# @app.post("/dropout/download/specials", description="Downloads a seasons behind the scenes and trailers, ignores main episodes.") +# async def dropoutDownload( +# background_tasks: BackgroundTasks, +# show: str = Form(...), +# season: int = Form(...), +# episode: Optional[int] = Form(None) +# ): +# try: +# logger.info(f'message=Received download request for specials of season {season} of {show}.') +# background_tasks.add_task(download.dropout.specials,show,season,episode) +# # download.dropout.show(show,season,episode) +# return JSONResponse(status_code=200, content={"status": "success", "message": "Series downloaded."}) +# except Exception as e: +# return JSONResponse(status_code=500, content={"status": "error", "message": str(e)}) @app.post("/ydl") async def ydl(background_tasks: BackgroundTasks, url: str = Form(...), location: str = Form(...)):