import subprocess from pathlib import Path from abc import ABC, abstractmethod class BaseService(ABC): @abstractmethod def name(self): pass @abstractmethod def slugify(self, text): pass @abstractmethod def discover_seasons(self, show_title, source_season=None, source_url=None): pass @abstractmethod def normalize_episode(self, source_title, output_title, entry): pass def download_episode(self, episode, entry, download_dir): """ Common download logic using yt-dlp. Services can override this if they need specific flags. """ # Create folder: "Show Name" (removing dots used in filenames) show_folder = Path(download_dir) / episode["show"].replace(".", " ") show_folder.mkdir(parents=True, exist_ok=True) output_template = str(show_folder / f"{episode['filename']}.%(ext)s") url = entry.get("webpage_url") or entry.get("url") if not url: print(" ❌ No URL found in entry") return False # Build command - using --netrc as a default safe bet for all cmd = [ "yt-dlp", "--netrc", "--no-progress", "-o", output_template, url ] result = subprocess.run(cmd) return result.returncode == 0