"""Fix switch hitter cards by regenerating with correct handedness and uploading to S3""" import sys import asyncio import aiohttp import boto3 from pathlib import Path # Add parent directory to path for imports sys.path.insert(0, "/home/cal/.claude/skills/paper-dynasty") from api_client import PaperDynastyAPI # Configuration SWITCH_HITTER_IDS = [ 12785, 12788, 12854, 12735, 12858, 12786, 12852, 12727, 12757, 12831, 12748, ] PLAYER_NAMES = [ "Bernie Williams", "Brian Roberts", "Carlos Beltran", "Chone Figgins", "Jimmy Rollins", "Jorge Posada", "Jose Reyes", "Mark Teixeira", "Nick Swisher", "Omar Vizquel", "Victor Martinez", ] CARDSET_ID = 27 NEW_DATE = "2025-11-12" # Tomorrow's date for cache-busting AWS_BUCKET = "paper-dynasty" AWS_REGION = "us-east-1" # Initialize API client api = PaperDynastyAPI(environment="prod", verbose=True) # Initialize S3 client s3_client = boto3.client("s3", region_name=AWS_REGION) async def fetch_and_save_card( session: aiohttp.ClientSession, player_id: int, player_name: str ) -> str: """Fetch card image from API and save locally""" card_url = ( f"https://pd.manticorum.com/api/v2/players/{player_id}/battingcard?d={NEW_DATE}" ) print(f"Fetching card for {player_name} (ID: {player_id})...") print(f" URL: {card_url}") async with session.get(card_url) as response: if response.status != 200: raise Exception(f"Failed to fetch card: HTTP {response.status}") # Save to temp directory temp_dir = Path("/tmp/switch_hitter_cards") temp_dir.mkdir(exist_ok=True) file_path = temp_dir / f"player-{player_id}-battingcard.png" with open(file_path, "wb") as f: f.write(await response.read()) print(f" ✓ Saved to {file_path}") return str(file_path) def upload_to_s3(file_path: str, player_id: int) -> str: """Upload card to S3 and return the URL""" s3_key = f"cards/cardset-{CARDSET_ID:03d}/player-{player_id}/battingcard.png" print(f" Uploading to S3: s3://{AWS_BUCKET}/{s3_key}") with open(file_path, "rb") as f: s3_client.put_object( Bucket=AWS_BUCKET, Key=s3_key, Body=f, ContentType="image/png", CacheControl="public, max-age=31536000", # 1 year cache ) # Return the S3 URL with cache-busting date s3_url = f"https://{AWS_BUCKET}.s3.{AWS_REGION}.amazonaws.com/{s3_key}?d={NEW_DATE}" print(f" ✓ Uploaded to S3: {s3_url}") return s3_url def update_player_image_url(player_id: int, s3_url: str): """Update player record with new S3 image URL""" print(f" Updating player {player_id} image URL...") result = api.patch("players", object_id=player_id, params=[("image", s3_url)]) print(" ✓ Updated player record") return result async def main(): print("=" * 80) print("FIXING SWITCH HITTER CARDS") print("=" * 80) print(f"Players to fix: {len(SWITCH_HITTER_IDS)}") print(f"New date: {NEW_DATE}") print(f"S3 Bucket: {AWS_BUCKET}") print("=" * 80) print() async with aiohttp.ClientSession() as session: for idx, player_id in enumerate(SWITCH_HITTER_IDS, 1): player_name = PLAYER_NAMES[idx - 1] print( f"\n[{idx}/{len(SWITCH_HITTER_IDS)}] Processing {player_name} (ID: {player_id})" ) print("-" * 80) try: # Step 1: Fetch card from API (triggers regeneration) file_path = await fetch_and_save_card(session, player_id, player_name) # Step 2: Upload to S3 s3_url = upload_to_s3(file_path, player_id) # Step 3: Update player record update_player_image_url(player_id, s3_url) print(f" ✅ COMPLETED: {player_name}") except Exception as e: print(f" ❌ ERROR: {e}") continue print("\n" + "=" * 80) print("ALL SWITCH HITTERS PROCESSED") print("=" * 80) print( f"\nVerify Bernie Williams: https://paper-dynasty.s3.us-east-1.amazonaws.com/cards/cardset-027/player-12785/battingcard.png?d={NEW_DATE}" ) if __name__ == "__main__": asyncio.run(main())