#!/usr/bin/env python3 from pathlib import Path from services.iview import ABCService # ------------------------- # Metadata files # ------------------------- DOWNLOAD_META = Path("./.download") HISTORY_FILE = DOWNLOAD_META / ".history" SERIES_FILE = DOWNLOAD_META / ".series" DOWNLOAD_META.mkdir(exist_ok=True) HISTORY_FILE.touch(exist_ok=True) SERIES_FILE.touch(exist_ok=True) # ------------------------- # Service registry # ------------------------- SERVICES = { "ABC": ABCService(), } # ------------------------- # Core Autograbber # ------------------------- class AutoGrabber: def __init__(self): self.history = self.load_history() self.series_list = self.load_series() # ------------------------- # History handling # ------------------------- def load_history(self): history = {} with open(HISTORY_FILE, "r") as f: for line in f: line = line.strip() if not line: continue if "|" in line: ep_id, filename = line.split("|", 1) history[ep_id.strip()] = filename.strip() else: # backwards compatibility history[line.strip()] = None return history def save_history(self): with open(HISTORY_FILE, "w") as f: for ep_id in sorted(self.history.keys()): filename = self.history[ep_id] if filename: f.write(f"{ep_id} | {filename}\n") else: f.write(f"{ep_id}\n") # ------------------------- # Series loading # ------------------------- def load_series(self): series = [] with open(SERIES_FILE, "r") as f: for line in f: line = line.strip() if not line: continue if "/" not in line: continue service_name, show_title = line.split("/", 1) series.append(( service_name.strip(), show_title.strip() )) return series # ------------------------- # Process a single show # ------------------------- def process_show(self, service_name, show_title): service = SERVICES.get(service_name.upper()) if not service: print(f"āŒ Unknown service: {service_name}") return print("\n==============================") print(f"šŸ“ŗ Show: {show_title}") print(f"šŸ“” Service: {service_name}") print("==============================") seasons = service.discover_seasons(show_title) if not seasons: print("āš ļø No seasons found") return for season_data in seasons: season_num = season_data["season"] data = season_data["data"] print(f"\nšŸ“¦ Processing Season {season_num}") for entry in data["entries"]: episode = service.normalize_episode( show_title, entry ) ep_id = episode["episode_id"] if not ep_id: continue filename = episode["filename"] # already downloaded if ep_id in self.history: print( f"ā© " f"{self.history[ep_id]} " f"(already downloaded)" ) continue print(f"āœ… {filename} → queued") success = service.download_episode( episode, entry ) if success: self.history[ep_id] = filename self.save_history() # ------------------------- # Main execution # ------------------------- def run(self): if not self.series_list: print("āš ļø No shows found in .series") return for service_name, show_title in self.series_list: self.process_show( service_name, show_title ) print("\nāœ… Autograbber run complete") # ------------------------- # Entry point # ------------------------- if __name__ == "__main__": AutoGrabber().run()