diff --git a/app/download.py b/app/download.py index c84ef51..b67f2ee 100644 --- a/app/download.py +++ b/app/download.py @@ -1,15 +1,6 @@ -from fastapi.responses import JSONResponse -import os, yt_dlp, json, requests +import os, yt_dlp, json, requests, re from bs4 import BeautifulSoup -import re - -# Define your patterns -reject_patterns = [ - re.compile(r'(?i).*behind.?the.?scenes.*'), - re.compile(r'(?i).*trailer.*'), - re.compile(r'(?i).*recap.*'), - re.compile(r'(?i).*last.looks.*'), -] +from urllib.parse import urlsplit class grab(): def season(url): @@ -21,6 +12,40 @@ class grab(): seasons = [item.replace(url+'/season:', '') for item in option_values] return seasons + def poster(url, save_dir='/data/posters/', force_download=False): + page_html = requests.get(url) + soup = BeautifulSoup(page_html.text, 'html.parser') + + # Find the first anywhere inside a .product-feature + feature_section = soup.find(class_='product-feature') + if not feature_section: + return None + + img_tag = feature_section.find('img', attrs={'data-image-primary': True}) or feature_section.find('img') + + if img_tag and img_tag.has_attr('src'): + img_url = img_tag['src'] + + # Use alt for filename if available, fallback to a generic name + alt_value = img_tag.get('alt', 'image') + path = urlsplit(img_url).path + ext = os.path.splitext(path)[-1] or '.jpeg' + + safe_name = re.sub(r'[\\/:*?"<>|]', '_', alt_value.replace(' ', '_')) + filename = f"{safe_name}{ext}" + filepath = os.path.join(save_dir, filename) + + if not os.path.exists(filepath) or force_download: + os.makedirs(save_dir, exist_ok=True) + img_data = requests.get(img_url).content + with open(filepath, 'wb') as handler: + handler.write(img_data) + + return filepath + else: + return None + + def thumbnail(ydl,url,location): # Extracting video information video_info = ydl.extract_info(url, download=False) @@ -179,6 +204,7 @@ class dropout(): name=url.replace('https://www.dropout.tv/','').replace('-s-',"'s-").replace('-',' ').title().replace('Of','of').replace("'S","'s") info_data['SHOW'] = name info_data['URL'] = url + info_data['POSTER'] = grab.poster(url) info_data['SEASONS'] = grab.season(url) json_data.append(info_data) @@ -218,34 +244,4 @@ class youtube(): with yt_dlp.YoutubeDL(dl_ops) as ydl: ydl.download([url]) - # grab.thumbnail(ydl,url,location) - - def downloadOptions(dl_ops): - if dl_ops['paths']['home'] == "/podcasts": - dl_ops['format'] = 'bestaudio/best[ext=mp3]' - dl_ops['postprocessors'] = [{ - 'key': 'FFmpegExtractAudio', - 'preferredcodec': 'mp3', - 'preferredquality': '192', - }, { - 'key': 'FFmpegMetadata', - 'add_metadata': True, - }] - elif dl_ops['paths']['home'] == "/asmr": - dl_ops['format'] = 'bestaudio/best[ext=mp3]' - dl_ops['postprocessors'] = [{ - 'key': 'FFmpegExtractAudio', - 'preferredcodec': 'mp3', - 'preferredquality': '192', - }, { - 'key': 'FFmpegMetadata', - 'add_metadata': True, - }] - elif dl_ops['paths']['home'] == "/nsfw": - dl_ops['format'] = 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best' - else: - dl_ops = { - 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best', - } - - return dl_ops \ No newline at end of file + # grab.thumbnail(ydl,url,location) \ No newline at end of file diff --git a/app/main.py b/app/main.py index 35c2026..4bc8c2f 100644 --- a/app/main.py +++ b/app/main.py @@ -33,7 +33,7 @@ async def dropoutSeries(): return JSONResponse(content=data) return JSONResponse(content={"error": "File not found"}, status_code=404) -@app.post("/dropout/download") +@app.post("/dropout/download", description="Download an entire season from episode 1. Ignores behind the scenes and trailers.") async def dropoutDownload( show: str = Form(...), season: int = Form(...), @@ -45,7 +45,7 @@ async def dropoutDownload( except Exception as e: return JSONResponse(status_code=500, content={"status": "error", "message": str(e)}) -@app.post("/dropout/download/specials") +@app.post("/dropout/download/specials", description="Downloads a seasons behind the scenes and trailers, ignores main episodes.") async def dropoutDownload( show: str = Form(...), season: int = Form(...),