This commit is contained in:
TylerCG 2025-04-26 08:46:30 -04:00
parent 4503dfa0b3
commit a02f91fdf2
2 changed files with 40 additions and 44 deletions

View File

@ -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 <img> 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)
@ -219,33 +245,3 @@ 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

View File

@ -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(...),