paper-dynasty-card-creation/fix_switch_hitters.py
Cal Corum 0a17745389 Run black and ruff across entire codebase
Standardize formatting with black and apply ruff auto-fixes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:24:33 -05:00

157 lines
4.3 KiB
Python

"""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())