#!/usr/bin/env python3 """ MTGJSON Data Downloader Downloads all MTGJSON data files and stores them for import. """ import gzip import json import os import sys from pathlib import Path from urllib.request import urlretrieve from urllib.parse import urljoin # MTGJSON API v5 base URL MTGJSON_API_V5 = "https://mtgjson.com/api/v5" # Files to download with their types MTGJSON_FILES = { "AllPrintings.psql.gz": { "name": "AllPrintings", "description": "Main cards database (PSQL format)", "type": "psql", }, "AllSetFiles.zip": { "name": "AllSetFiles", "description": "Set and card data", "type": "zip", }, "AllDeckFiles.zip": { "name": "AllDeckFiles", "description": "Deck data", "type": "zip", }, "AllIdentifiers.json.gz": { "name": "AllIdentifiers", "description": "Card identifiers", "type": "json", }, "CardTypes.json.gz": { "name": "CardTypes", "description": "Card types", "type": "json", }, "DeckList.json.gz": { "name": "DeckList", "description": "Deck list metadata", "type": "json", }, "Keywords.json.gz": { "name": "Keywords", "description": "Card keywords", "type": "json", }, "SetList.json.gz": { "name": "SetList", "description": "Set list metadata", "type": "json", }, } def get_downloads_dir() -> Path: """Get the downloads directory path.""" data_dir = Path(os.environ.get("MTGDATA_DIR", "/app/data")) downloads_dir = data_dir / "mtgjson" / "downloads" downloads_dir.mkdir(parents=True, exist_ok=True) return downloads_dir def download_file(url: str, destination: Path) -> bool: """Download a file from URL to destination.""" try: print(f"Downloading {url}...") urlretrieve(url, destination) size_mb = destination.stat().st_size / (1024 * 1024) print(f" ✓ Downloaded to {destination} ({size_mb:.1f} MB)") return True except Exception as e: print(f" ✗ Failed to download {url}: {e}") return False def download_all_files() -> list[Path]: """Download all MTGJSON files.""" downloads_dir = get_downloads_dir() downloaded_files = [] print("=== MTGJSON Data Download ===\n") for filename, file_info in MTGJSON_FILES.items(): url = urljoin(MTGJSON_API_V5, filename) destination = downloads_dir / filename if download_file(url, destination): downloaded_files.append(destination) else: print(f" ⚠ Continuing with downloaded files only") print(f"\n=== Download Complete ===") print(f"Downloaded {len(downloaded_files)} files to {downloads_dir}") return downloaded_files def verify_downloads(downloaded_files: list[Path]) -> bool: """Verify all expected files are downloaded.""" print("\n=== Verifying Downloads ===\n") all_ok = True for filename, file_info in MTGJSON_FILES.items(): filepath = Path(get_downloads_dir() / filename) if filepath.exists(): size_mb = filepath.stat().st_size / (1024 * 1024) print(f"✓ {filename:30} ({size_mb:.1f} MB)") else: print(f"✗ {filename:30} (MISSING)") all_ok = False if all_ok: print("\n✓ All files downloaded successfully") else: print("\n⚠ Some files are missing") return all_ok def get_file_list() -> list[Path]: """Get list of all downloaded files.""" downloads_dir = get_downloads_dir() files = [downloads_dir / filename for filename in MTGJSON_FILES.keys()] return [f for f in files if f.exists()] if __name__ == "__main__": downloaded = download_all_files() verify_downloads(downloaded)